How to use DirectX 2D to draw .pngs?

I recently asked "How to use bitmaps?", and I was advised to use directX 2D to do so. Well, I like the idea of learning DirectX, so I went ahead and heeded the advice. Well, I am still having trouble drawing pictures on the window, so can I get some tips on how to do it? By tips, I mean a full explanation. After a while of searching the internet, typing out entire things, I figured I would just ask. So... here I am, asking.
Btw, I still haven't figured out how to draw BMPs to windows, but since all I have on my computer is PNGs, I figured I would use those instead. I read that it is the same process.
closed account (13bSLyTq)
You could create an plane then add the PNG as an texture and ensure the plane is black which could create the illusion of you drawing it to the screen.

Nevertheless, its an idea and I'm more of OpenGL guy than DirectX.
It's called Direct2D, not DirectX 2D. As far as I know Direct2D interoperates with DirectX(and uses it behind the scenes) but isn't actually a part of it.

You might want to read through the topics on this page:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd370990%28v=vs.85%29.aspx

In general the steps to render an image with Direct2D are as follows:

1) Create an ID2D1Factory object. See the examples here:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd371246%28v=vs.85%29.aspx

2) Via the ID2D1Factory interface, create a DC render target by calling the CreateDCRenderTarget() method.

3) Via the ID2D1DCRenderTarget interface, call the BindDC() method to associate the render target with the window DC. Every time the window size changes you need to call BindDC().

4) Via the ID2D1DCRenderTarget interface, create device-dependent resources, such as bitmaps and gradients, by calling the appropriate Create*() methods. One of the CreateBitmap() overloads allows you to create a Direct2D bitmap from a Windows Imaging Component(WIC) bitmap.

5) Via the ID2D1DCRenderTarget interface, render device-dependent resources by calling the appropriate Draw*() methods in between calls to the BeginDraw() and EndDraw() methods. If EndDraw() returns D2DERR_RECREATE_TARGET you need to re-create the render target and all device-dependent resources(not sure under what circumstances this happens).

WIC reference:

http://msdn.microsoft.com/en-us/library/windows/desktop/ee719902%28v=vs.85%29.aspx

Using WIC is a bit more complicated than Direct2D, but loading an image from disk is pretty simple. The example on this page shows how:

http://msdn.microsoft.com/en-us/library/windows/desktop/ee690281%28v=vs.85%29.aspx

That example shows how to get the frame count as some formats support multiple frames. Assuming windows has a codec installed you should be able to load any image format with WIC. To retrieve an actual frame you need to call the GetFrame() method of the IWICBitmapDecoder.

Additionally, to make the image compatible with Direct2D the pixel format has to be converted to 32bppBGRA. To do that you have to call the CreateFormatConverter() method of the IWICImagingFactory and then call the Initialize() method of the IWICFormatConverter().

I didn't include any code but you can look up all the interfaces and methods I mentioned on MSDN to find how to use them.
Last edited on
closed account (z05DSL3A)
http://www.cplusplus.com/forum/windows/139321/#msg737170
@Grey Wolf just in case you didn't see I said that I recently asked that, but I am still not getting it and to get a little bit more in detail.
I recently asked "How to use bitmaps?"


I figured that this was too off topic to ask in that same thread, because recently on Unity Answers I asked a sort-of-related-question in the same thread and got scolded for it.

Anyway, as for knn9, thanks again! I am pretty sure you were the one who answered my other question, so thanks for being a big help for me.
closed account (z05DSL3A)
AceDawg45,

I wasn't sure that you had read it or not as this question looks the same as the other.

I'm not sure how much more detail you want if Microsofts reference implementation is not detailed enough for you.
Okay, so after about an hour of searching on the internet (7 pages of google search results) I have still found nothing on this subject. Well, no, i have, but nothing has worked for me. There are two tutorials on this on MSDN, but the one said at the bottom to go to another tutorial, since the one doesn't work, and linked me to it.

The one it linked me to was a horrible tutorial and I didn't learn anything from it.

I don't want to, but my next option is to search youtube for an answer.

Do you guys know any tutorials on this?
closed account (z05DSL3A)
Do you understand COM (Component Object Model) and how to use it?
I have heard of it, but never really used it. Isn't like .NET?
closed account (z05DSL3A)
Its a 'platform-independent, distributed, object-oriented system for creating binary software components that can interact.' [1]

The reason I asked is that Direct2D uses a "lightweight COM" approach to its interface, so it may be of use to do some reading on COM to help you understand Direct2D.

Edit:
and Windows Imaging Component (WIC) is COM
____________________________________________________
[1] http://msdn.microsoft.com/library/ms680573(VS.85).aspx
Last edited on
Thanks for the advice. I found a function to load a bitmap from a file on MSDN, but they didn't explain it too well. Here it is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
HRESULT LoadBitmapFromFile(ID2D1RenderTarget *pRenderTarget, IWICImagingFactory *pIWICFactory, PCWSTR uri,
	UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap **ppBitmap)
{
	IWICBitmapDecoder *pDecoder = NULL;
	IWICBitmapFrameDecode *pSource = NULL;
	IWICStream*pStream = NULL;
	IWICFormatConverter *pConverter = NULL;
	IWICBitmapScaler *pScaler = NULL;

	HRESULT hr = pIWICFactory->CreateDecoderFromFilename(uri, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder);

	if (SUCCEEDED(hr)){
		hr = pDecoder->GetFrame(0, &pSource);
	}

	if (SUCCEEDED(hr)){
		// Convert Image format to 32bppPBGRA
		// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
		hr = pIWICFactory->CreateFormatConverter(&pConverter);
	}

	if (SUCCEEDED(hr)){
		hr = pConverter->Initialize(
			pSource,
			GUID_WICPixelFormat32bppPBGRA,
			WICBitmapDitherTypeNone,
			NULL,
			0.f,
			WICBitmapPaletteTypeMedianCut
			);
	}

	if (SUCCEEDED(hr)){
		
		// Create a Direct2D bitmap from the WIC bitmap
		hr = pRenderTarget->CreateBitmapFromWicBitmap(
			pConverter,
			NULL,
			ppBitmap
			);
	}

	SafeRelease(&pDecoder);
	SafeRelease(&pSource);
	SafeRelease(&pStream);
	SafeRelease(&pConverter);
	SafeRelease(&pScaler);

	return hr;
}


Now, I have seen a lot of these if statements to see if SUCCEEDED(hr) returns true on MSDN. What exactly does that do?

Also, I *guess* that the function up above decodes the image into something c++ can read, then loads it from file. Am I right?
closed account (z05DSL3A)
SUCCEEDED(hr) is an error checking method.

hr, a HRESULT, get assigned the result of the function calls. the SUCCEEDED macro is used check that the preceding function succeeded before calling the next one, or if it failed it bypasses the remaining calls, cleans up an returns the error.
Topic archived. No new replies allowed.