directdraw 2D example code
다이얼로그 박스에 그림을 그릴 때 DC대신 directdraw를 사용한 간단한 예제다.
BOOL CreateD2D()에서 DDraw 2D관련 리소스를 생성하고, void DestoryD2D()에서 해제한다. 실제 그림을 그리는 함수는 void Draw()이다.
3. 다이얼로그 클래스에 1에서 생성한 picture control의 컨트롤 변수를 추가한다. 변수 형식은 위 2에서 만든 class를 사용한다.
4. 실행화면은 아래 그림과 같다. 1에서 생성한 picture control 윈도우에 박스와 글이 써진 것을 볼 수 있다.
1.다이얼로그 박스에 picture control을 추가한다.
2. CStatic을 기본으로 하는 mfc class를 생성한다.
DDraw2DCtrl.h
class CDDraw2DCtrl : public CStatic
{
DECLARE_DYNAMIC(CDDraw2DCtrl)
private:
user_lock
m_lock;
ID2D1Factory
*m_pD2DFactory;
IDWriteFactory
*m_pDWriteFactory;
ID2D1HwndRenderTarget
*m_pRenderTarget;
ID2D1SolidColorBrush
*m_pBrush;
IDWriteTextFormat
*m_pTextFormat;
void DestoryD2D();
BOOL CreateD2D();
void Draw();
public:
CDDraw2DCtrl();
virtual ~CDDraw2DCtrl();
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
protected:
DECLARE_MESSAGE_MAP()
};
DDraw2DCtrl.cpp
#include "stdafx.h"
#include "DDraw2DCtrl.h"
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) if (x) { x->Release(); x = NULL;}
#endif
// CDDraw2DCtrl
IMPLEMENT_DYNAMIC(CDDraw2DCtrl, CStatic)
CDDraw2DCtrl::CDDraw2DCtrl()
{
m_pD2DFactory = NULL;
m_pDWriteFactory = NULL;
m_pRenderTarget = NULL;
m_pBrush = NULL;
m_pTextFormat = NULL;
}
CDDraw2DCtrl::~CDDraw2DCtrl()
{
DestoryD2D();
}
BEGIN_MESSAGE_MAP(CDDraw2DCtrl, CStatic)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
// CDDraw2DCtrl 메시지 처리기입니다.
void CDDraw2DCtrl::OnPaint()
{
CPaintDC dc(this); // device context for
painting
// TODO: Add your message handler code here
// Do not call CStatic::OnPaint() for
painting messages
CUserAutoLock lock(&m_lock);
Draw();
}
BOOL CDDraw2DCtrl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
//return CStatic::OnEraseBkgnd(pDC);
}
void CDDraw2DCtrl::DestoryD2D()
{
SAFE_RELEASE(m_pBrush);
SAFE_RELEASE(m_pTextFormat);
SAFE_RELEASE(m_pRenderTarget);
SAFE_RELEASE(m_pDWriteFactory);
SAFE_RELEASE(m_pD2DFactory);
}
BOOL CDDraw2DCtrl::CreateD2D()
{
HRESULT hr;
RECT rc;
if (m_pD2DFactory || !GetSafeHwnd())
return FALSE;
hr =
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
&m_pD2DFactory);
if (FAILED(hr))
{
MessageBox(TEXT("D2D1CreateFactory fail"));
return FALSE;
}
GetClientRect(&rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right -
rc.left, rc.bottom - rc.top);
hr =
m_pD2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(GetSafeHwnd(), size),
&m_pRenderTarget);
if (FAILED(hr))
{
MessageBox(TEXT("m_pD2DFactory->CreateHwndRenderTarget fail"));
DestoryD2D();
return FALSE;
}
hr =
DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
__uuidof(m_pDWriteFactory),
reinterpret_cast<IUnknown **>(&m_pDWriteFactory)
);
if (FAILED(hr))
{
MessageBox(TEXT("DWriteCreateFactory fail"));
DestoryD2D();
return FALSE;
}
hr =
m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black),
&m_pBrush);
if (FAILED(hr))
{
MessageBox(TEXT("m_pD2DFactory->CreateSolidColorBrush fail"));
DestoryD2D();
return FALSE;
}
hr =
m_pDWriteFactory->CreateTextFormat(TEXT("Consolas"),
NULL,
DWRITE_FONT_WEIGHT_BOLD,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
25,
L"", //locale
&m_pTextFormat
);
if (FAILED(hr))
{
MessageBox(TEXT("m_pD2DFactory->CreateSolidColorBrush fail"));
DestoryD2D();
return FALSE;
}
m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
return TRUE;
}
void CDDraw2DCtrl::Draw()
{
CRect rect;
HRESULT hr;
if (!m_pRenderTarget)
{
if (!CreateD2D())
{
return;
}
}
// Resize
GetClientRect(&rect);
D2D1_SIZE_U size = D2D1::SizeU(rect.Width(),
rect.Height());
m_pRenderTarget->Resize(size);
// Begin Draw
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
/* Draw Rect
*/
m_pBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Red));
m_pRenderTarget->DrawRectangle(
D2D1::RectF(rect.left +
rect.Width() / 10, rect.top + rect.Height() / 10, rect.right -
rect.Width() / 10, rect.bottom - rect.Height() / 10),
m_pBrush
);
/*DrawText
*/
m_pBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black));
CString csText = TEXT("사장님 나빠요");
m_pRenderTarget->DrawText(
csText.GetString(),
wcslen(csText.GetString()),
m_pTextFormat,
D2D1::RectF(rect.left,
rect.top, rect.right, rect.bottom),
m_pBrush
);
hr = m_pRenderTarget->EndDraw();
}
BOOL CreateD2D()에서 DDraw 2D관련 리소스를 생성하고, void DestoryD2D()에서 해제한다. 실제 그림을 그리는 함수는 void Draw()이다.
3. 다이얼로그 클래스에 1에서 생성한 picture control의 컨트롤 변수를 추가한다. 변수 형식은 위 2에서 만든 class를 사용한다.
4. 실행화면은 아래 그림과 같다. 1에서 생성한 picture control 윈도우에 박스와 글이 써진 것을 볼 수 있다.
5. 아래 msdn에서 더 많은 자료를 찾아볼 수 있다.
댓글
댓글 쓰기