1. Direct2D
GDI를 사용하는 것보다 좀 더 좋은 품질의 그림을 그리고 싶다면 Direct2D를 사용하면 됩니다.
Direct2D는 GDI와 달리 AntiAlias 기능을 사용하기 떄문에 GDI로 그린 그림보다 더 좋은 결과를 보여줍니다.
Direct2D는 GDI+보다 최신의 API를 통해 구현되어 있고 현재도 버전이 업데이트 되고 있습니다. (DX11, DX12등)
Direct2D는 윈도우의 RDP(원격 데스크톱 프로토콜) 인프라를 사용하여 원격으로도 표시할 수 있습니다.
개발자가 렌더링을 디스플레이 컴퓨터의 GPU에 의해 처리되는지, 로컬 렌더링 이후 비트맵으로 전송되는지 여부를 선택할 수 있습니다.
2. Direct2D 사용
COM 라이브러리 사용하기
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
, _In_ LPSTR lpszCmdParam, _In_ int nCmdShow)
{
CoInitializeEx(NULL, COINIT_ApARTMENTTHREADED);
//... 생략
CoUninitialize();
return (int)msg.wParam;
}
Direct2D는 COM(Component Object Model)으로 만들어져 있기 때문에 프로그램에서 COM 라이브러리를 사용하기 위해서는 CoInitalizeEx 함수를 호출해야 합니다.
헤더
#include <d2d1.h>
#pragma comment(lib, "D2D1.lib")
// 네임 스페이스 생략
using namespace D2D1;
Factory 객체와 Render Target 객체의 주소를 저장할 변수 선언.
Direct2D를 사용하기 위해서는 최소 두 가지 객체 생성이 필요한데, 다른 객체를 생성하기 위한 Factory 객체와 화면에 그림을 그릴 때 사용하는 Render Target 객체입니다.
ID2D1Factory *gp_factory;
ID2D1HwndRenderTarget *gp_render_target;
Factory 객체 생성
Direct2D 기술을 사용하기 위한 객체 생성을 위해서는 Direct2D를 위한 Factory 객체를 생성해야 합니다.
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
, _In_ LPSTR lpszCmdParam, _In_ int nCmdShow)
{
// 컴포넌트 초기화
CoInitializeEx(NULL, COINIT_APARTMENT
// Factory 객체 생성.
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &gp_factory);
//... 생략
//사용하던 factory 객체 해제
gp_factory->Release();
// 컴포넌트 사용 해제
CoUninitialize();
}
Render Target 객체 생성
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
, _In_ LPSTR lpszCmdParam, _In_ int nCmdShow)
{
// 컴포넌트 초기화
CoInitializeEx(NULL, COINIT_APARTMENT
// Factory 객체 생성.
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &gp_factory);
//... 생략
// 사용하던 factory 객체 해제
gp_factory->Release();
// 컴포넌트 사용 해제
CoUninitialize();
}
3. Direct2D 그리기 예제
void testDrawDirectCircle(HWND hWnd);
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage) {
case WM_CREATE:
{
RECT r;
GetClientRect(hWnd, &r);
// Render Target 생성
gp_factory->CreateHwndRenderTarget(RenderTargetProperties(),
HwndRenderTargetProperties(hWnd, SizeU(r.right, r.bottom)),
&gp_render_target);
}
case WM_CLOSE:
{
int check = MessageBox(hWnd, L"프로그램을 종료하시겠습니까?",
L"종료 확인:", MB_ICONQUESTION | MB_OKCANCEL);
if (IDCANCEL == check)
return 0;
break;
}
case WM_PAINT:
{
testDrawDirectCircle(hWnd);
return 0;
}
case WM_DESTROY:
if (gp_render_target != NULL)
{
gp_render_target->Release();
gp_render_target = NULL;
}
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
void testDrawDirectCircle(HWND hWnd)
{
ValidateRect(hWnd, NULL);
gp_render_target->BeginDraw();
gp_render_target->Clear(ColorF(0.0f, 0.8f, 1.0f));
D2D1_ELLIPSE my_region;
// 타원 중싱점 (100, 100) 설정
my_region.point.x = 100;
my_region.point.y = 100;
my_region.radiusX = 50.0f; // 타원의 X축(수평)방향 반지름
my_region.radiusY = 50.0f; // 타원의 X축(수평)방향 반지름
ID2D1SolidColorBrush* p_yellow_brush = NULL;
gp_render_target->CreateSolidColorBrush(ColorF(1.0f, 1.0f, 0.0f), &p_yellow_brush);
gp_render_target->FillEllipse(my_region, p_yellow_brush);
p_yellow_brush->Release();
p_yellow_brush = NULL;
gp_render_target->EndDraw();
}
4. 참조
https://blog.naver.com/tipsware/221125856649
Win32에서 Direct2D 사용하기
: Win32 프로그래밍 관련 전체 목차 http://blog.naver.com/tipsware/221059977193...
blog.naver.com
'Win32 API' 카테고리의 다른 글
18. Win32 API - Win32 클래스화(2 - 설명) (0) | 2024.03.27 |
---|---|
17. Win32 API - Win32 클래스화(1 - 전체 코드) (0) | 2024.03.23 |
15. Win32 API - GDI+ (0) | 2024.03.16 |
14. Win32 API - StockObject (0) | 2024.03.09 |
13. Win32 API - 윈도우 좌표 (0) | 2024.03.09 |