Drawing part of image in Direct2D
Since GDI+ is pretty (ridiculously) slow, I've decided to migrate to Direct2D. I've looked up many topics on many forums (including this one), but with no success (it may also be caused by the fact that's pretty late) and the Direct2D documentation is pretty slim still (and confusing, for me at least).
Anyway, I've got a .PNG that I open in Direct2D and want to draw only a part of it once every 20ms.
Initialize D2D stuff
ID2D1Factory* d2dFactory = NULL; IWICImagingFactory* d2dWICFactory = NULL; IWICBitmapDecoder* d2dDecoder = NULL; IWICFormatConverter* d2dConverter = NULL; ID2D1HwndRenderTarget* d2drender = NULL; IWICBitmapFrameDecode* d2dBmpSrc = NULL; ID2D1Bitmap* d2dBmp = NULL; /* initialize all the good stuff */ HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), NULL, (void**)&d2dFactory); D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); hr = d2dFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(zgE->getWnd(), size), &d2drender); hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (void**)(&d2dWICFactory)); hr = d2dWICFactory->CreateDecoderFromFilename(L"tile_1.png", NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &d2dDecoder); hr = d2dWICFactory->CreateFormatConverter(&d2dConverter); hr = d2dDecoder->GetFrame(0, &d2dBmpSrc); hr = d2dConverter->Initialize(d2dBmpSrc, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); hr = d2drender->CreateBitmapFromWicBitmap(d2dConverter, NULL, &d2dBmp);
/* draw the image */ D2D1_RECT_F rect = D2D1::RectF(x, y, x + size.width, y + size.height); d2drender->DrawBitmap(d2dBmp, &rect);
However, I can't get it to draw only a part of it, lets say 20 by 20 pixels. I've fiddled with DrawBitmap() and with differently sized rects, but the result isn't cropping the image.
Is there any way to do it besides layering, since I don't want to layer the image at each frame?
Mainly three steps
- Create the entire bitmap from file
- Get part of the entire bitmap by calling CopyFromBitmap
- Draw bitmap created in step 2.
ID2D1RenderTarget::DrawBitmap ( http://msdn.microsoft.com/en-us/library/windows/desktop/dd371880(v=vs.85).aspx ) takes up to 5 parameters, the last one being the source rectangle. You're only supplying the first 2 parameters, and the default for the source rectangle is to use the entire bitmap. So, the solution is simply to supply this parameter with a D2D1::RectF(0, 0, 20, 20) if you only want to draw from that portion of it.