距离上一篇文章更新已经很长时间了,那个游戏也做完了,能跑起来,联网效果也很好(没错那是一个网络游戏),有时间的话也会考虑把怎么做一个稍具规模的游戏的笔记贴出来吧,这里我们讲怎么用Direct2D贴图。
GDI里面,有一个类叫CImage,特别方便,想要读什么图片只需要Load一下,然后想画的时候,只需要说一句some_image.Draw(pDC, ...)
就可以了,然而可惜的是D2D里面没有那么好用的类,不过这并不是什么问题,我们可以先看看这些东西怎么做,然后封装一个类出来就好了。
其实一般来讲,贴图只有两个主要的步骤:
- 把图片读进来
- 把图片贴在屏幕上
把图片读进来其实并不像想象中的那么简单。还记得IWICImagingFactory
这个类吗?这个类就是负责加载外部图片资源的。和GDI不一样的是,加载图片资源的时候需要指定RenderTarget,你读进来的图片是和RenderTarget绑定的,这很可能令从GDI转过来的人感到不适应,因为GDI里面读图片的时候根本不要求指定DC。读进来以后,图片需要经过一系列的转换,最后存到一个叫ID2D1Bitmap的东西里面。整体来看,读一个图片的方法是这样的:
//三个参数,第一个是IWICImagingFactory的指针,第二个是RenderTarget的指针,第三个是图片的路径
HRESULT CD2DImage::Load(IWICImagingFactory * pIWICFactory,ID2D1RenderTarget * pd2dDevice,LPCTSTR pszResource)
{
//重复操作
Release();
HRESULT hr=S_OK;
IWICStream *pStream=NULL;
IWICBitmapScaler *pScaler=NULL;
IWICBitmapDecoder *pDecoder=NULL;
IWICBitmapFrameDecode *pSource=NULL;
IWICFormatConverter *pConverter=NULL;
hr = pIWICFactory->CreateDecoderFromFilename(
pszResource,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
hr = pIWICFactory->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{