D2D와 게임엔진

Direct2D 기본 사용법 3 (이미지 출력)

햄시나 2024. 8. 5. 17:06

랜더타겟에 있는 함수인 DrawBitmap() 함수를 이용한다. 

그리고 저 함수는 ID2D1Bitmap 요놈이 필요하다.

 

 

갑자기 WICImagingFactory가 뭔가 싶을 것이다. (수업 때 들었는지 기억도 안남)

WIC란 WindowsImageComponent의 약자다.

아무튼 얘가 필요한 이유는 이미지파일로 D2D1Bitmap을 생성하려고 하기 때문임.

파일확장자 BMP,GIF,ICO,JPG,PNG,TIF,DDS 다 된다.

 

이제 코드로 알아보자.

// 처음과 이어지는 코드입니다. 밑의 헤더와 라이브러리 추가하기
#include <wincodec.h>
#pragma comment(lib,"windowscodecs.lib")

// D2D1비트맵 생성을 위한 이미지 처리 인터페이스
IWICImagingFactory* _pWICFactory;
ID2D1Bitmap* _pD2DBitmap = nullptr;

// 새로운 함수 등장! 함수의 이름 그대로 함수의 역할을 받아들이면 된다. //
HRESULT CreateD2DBitmapFromFile(const WCHAR* szFilePath,ID2D1Bitmap** ppID2D1Bitmap)
{
	HRESULT hr;
    
    IWICBitmapDecoder* pDecoder = NULL;
	IWICFormatConverter* pConverter = NULL;
    // 디코더 생성해주기
    hr = _pWICFactory->CreateDecoderFromFilename(
    szFilePath,                      // 받아온 이미지의 주소
	NULL,                            // Do not prefer a particular vendor
	GENERIC_READ,                    // Desired read access to the file
	WICDecodeMetadataCacheOnDemand,  // Cache metadata when needed
	&pDecoder                        // Pointer to the decoder
	);
    
    //WICBitmapDecoder로 0 Frame 얻기 
	//Decode(파일 포맷에 따른 압축 해제 후 메모리에 비트맵 생성)
	IWICBitmapFrameDecode* pFrame = NULL;
	if (SUCCEEDED(hr))
	{
		hr = pDecoder->GetFrame(0, &pFrame);
	}
    //WICFormatConverter에서 Frame소스로 32비트 픽셀 포맷 변환
    //컨버터 생성하기
	if (SUCCEEDED(hr))
	{
		hr = _pWICFactory->CreateFormatConverter(&pConverter);
	}
    if (SUCCEEDED(hr))
	{
		hr = pConverter->Initialize(
		pFrame,                          // Input bitmap to convert
		GUID_WICPixelFormat32bppPBGRA,   // Destination pixel format
		WICBitmapDitherTypeNone,         // Specified dither pattern
		NULL,                            // Specify a particular palette 
		0.f,                             // Alpha threshold
		WICBitmapPaletteTypeCustom       // Palette translation type
		);
	}
	//RenderTarget이 Converter소스로 D2D1Bitmap생성      
    if (SUCCEEDED(hr))
	{		
		hr = _pRenderTarget->CreateBitmapFromWicBitmap(pConverter, NULL, ppID2D1Bitmap);
	}
    // 파일을 사용할때마다 다시 만든다.
	if(pConverter)  
  	  	pConverter->Release();
   
	if (pDecoder)
    	pDecoder->Release();

	if (pFrame)
    	pFrame->Release();

	return hr;
}
// 이제 다시 익숙한 함수 등장 //
BOOL InitDirect2D()
{	
	hr = CoInitialize(NULL);
	// 대충 렌더타겟 생성됨
    if (SUCCEEDED(hr))
	{
		// WIC팩토리 생성하기
		hr = CoCreateInstance(
		CLSID_WICImagingFactory,
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_PPV_ARGS(&_pWICFactory)
		);
	}
	if (SUCCEEDED(hr))
	{
    	// 우리가 위에 열심히 만든 함수가 호출됨.
    	hr = CreateD2DBitmapFromFile(L"../Resource/atk_1.png", &_pD2DBitmap);
	}
	return true;
}
// 그리고 이제 여기에서 쓰임.
int WINAPI WinMain(생략)
{
	//...생략
    while (TRUE)
    {
    	g_pRenderTarget->BeginDraw();
		g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CadetBlue));
		g_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); // 변환 초기화

		//1. 0,0 위치에 비트맵 전체영역 그린다. (변환은 초기화)
		g_pRenderTarget->DrawBitmap(g_pD2DBitmap);			
		g_pRenderTarget->EndDraw();
	}
}