有个基本的DEVICE设备后后面就是如何利用这个设备来显示图形了。swapchain的概念来是利用双缓冲的办法来解决窗口刷新的办法,也可以利用这个思路解决FORM的控件闪动的问题。道理就不细说了,都是十几年前老掉牙的话题。先建立个"SwapChain.h"的头文件:
struct SwapChain{
Device device;//显示设备
IDXGISwapChain* chain;//渲染缓冲区
ID3D11RenderTargetView* rtv;//渲染内容的Buffer
ID3D11DepthStencilView* dsv;//深度信息的Buffer
D3D11_TEXTURE2D_DESC desc;//当前swapchain的描述
HWND handle;//捆绑的窗口
void Create(Device dev,HWND hWnd,int sample)//sample的选项是设定抗锯齿的级别根据显卡可以是1-2-4-8-16-32
{
device = dev;
handle=hWnd;
Viewport vp =Viewport(hWnd);
device.SetViewport(vp);
desc.Width = vp.Width;
desc.Height =vp.Height;
desc.SampleDesc.Count = sample;
desc.SampleDesc.Quality = 0;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_D32_FLOAT;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
CreateSwapChain(hWnd);
CreateChainRD();//生成渲染的Buffer
}
void CreateChainRD()
{
device.CreateDSV(dsv,desc);
device.CreateRTV(rtv,chain);
device.SetRenderTarget(1,rtv, dsv);
}
void Clear(Vector4 c)//清空前次渲染
{
device.ClearRTV(rtv, c);
device.ClearDSV(dsv, D3D11_CLEAR_DEPTH);
}
void Present() { chain->Present(0,0); }
void Dispose(){ Kill(chain);Kill( dsv);Kill( rtv); }
void Resize()// 当窗口大小变化事件
{
Viewport vp =Viewport(handle);
if(vp.Width<16||vp.Height<16)return;
desc.Width = vp.Width;
desc.Height =vp.Height;
device.SetViewport(vp);
Kill( dsv);Kill( rtv);
DXGI_SWAP_CHAIN_DESC Desc;
ZeroMemory( &Desc, sizeof( DXGI_SWAP_CHAIN_DESC ) );
chain->GetDesc(&Desc);
desc.Width= Desc.BufferDesc.Width=vp.Width;
desc.Height= Desc.BufferDesc.Height=vp.Height;
chain->ResizeBuffers(Desc.BufferCount,desc.Width,desc.Height,
Desc.BufferDesc.Format,Desc.Flags);
chain->ResizeTarget(&Desc.BufferDesc);
CreateChainRD();
}
上面的语法描述极其简单但它适应了所有的显示情况。我要做的就是把它捆绑到它的渲染工作区上了。
下面的图片使用了程序网格和两个程序创建的模型,文字的内容是相机的矩阵和汉字字体的支持。