Skip to content

Instantly share code, notes, and snippets.

@TheVice
Created August 31, 2018 22:52
Show Gist options
  • Save TheVice/34967f0e61fb751728943a3e458b1806 to your computer and use it in GitHub Desktop.
Save TheVice/34967f0e61fb751728943a3e458b1806 to your computer and use it in GitHub Desktop.
Fork of "Pluralsight - Direct2D Fundamentals(2012) by Kenny Kerr" created while study. Information and video tutorial - http://www.pluralsight.com/courses/direct2d-fundamentals Author - @kennykerr, http://kennykerr.ca, https://github.com/kennykerr
cmake_minimum_required(VERSION 2.8.12.2)
project("Pluralsight - Direct2D Fundamentals (2012)")
set(READY_TO_BUILD FALSE)
# Request Visual Studio
if(MSVC)
# Request Visual Studio 2012+
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.0)
set(READY_TO_BUILD TRUE)
else()
message("Host Visual Studio must be at least 2012 (MSVC 17.0)")
endif()
else()
message("This project require Visual Studio 2012 and above")
endif()
if(READY_TO_BUILD)
# Library
set(COMMON_LIBRARY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/)
file(GLOB H_Files ${COMMON_LIBRARY_PATH}/*.h)
file(GLOB INL_Files ${COMMON_LIBRARY_PATH}/*.inl)
# Lessons
file(GLOB Lessons RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(Lesson ${Lessons})
if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${Lesson})
string(FIND ${Lesson} ".cpp" pos REVERSE)
if(NOT (-1 EQUAL ${pos}))
string(SUBSTRING ${Lesson} 0 ${pos} LessonName)
set(LESSON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${Lesson})
add_executable(${LessonName} WIN32 ${LESSON_SOURCE} ${H_Files} ${INL_Files})
target_link_libraries(${LessonName} d2d1)
target_include_directories(${LessonName} PRIVATE ${COMMON_LIBRARY_PATH})
endif()
endif()
endforeach()
endif()
{
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"configurations": [
{
"name": "x86-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x86" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "x86-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x86" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
}
]
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Precompiled.h"
#include <wrl.h>
#include <tchar.h>
struct __declspec(uuid("718B6373-6F92-473A-BB4D-A82E4CE70D58")) __declspec(
novtable)
IBird : IUnknown
{
virtual HRESULT __stdcall HelloWorld() = 0;
};
struct Chicken :
Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IBird>
{
Chicken()
{
TRACE(TEXT("Cheep.\n"));
}
~Chicken()
{
TRACE(TEXT("Fried chicken anyone?\n"));
}
HRESULT __stdcall HelloWorld()
{
TRACE(TEXT("Cluck!\n"));
return S_OK; // | E_FAIL
}
};
HRESULT CreateChicken(IBird** aChicken)
{
auto made = Microsoft::WRL::Make<Chicken>();
if (!made)
{
return E_OUTOFMEMORY;
}
*aChicken = made.Detach();
return S_OK;
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hInstance;
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Microsoft::WRL::ComPtr<IBird> chicken;
HR(CreateChicken(chicken.GetAddressOf()));
HR(chicken->HelloWorld());
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Precompiled.h"
#include <tchar.h>
typedef LRESULT(* MessageCallback)(HWND, WPARAM, LPARAM);
struct MessageHandler
{
UINT mMessage;
MessageCallback mHandler;
};
static MessageHandler gHandlers[] =
{
{
WM_PAINT, [](HWND aWindow, WPARAM, LPARAM) -> LRESULT
{
PAINTSTRUCT ps;
VERIFY(BeginPaint(aWindow, &ps));
TRACE(TEXT("Paint!\n"));
EndPaint(aWindow, &ps);
return 0;
}
},
{
WM_DESTROY, [](HWND, WPARAM, LPARAM) -> LRESULT
{
PostQuitMessage(0);
return 0;
}
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
WNDCLASS wc = {};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("Window");
wc.lpfnWndProc = [](HWND aWindow, UINT aMessage, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
for (auto h = gHandlers; h != gHandlers + sizeof(gHandlers) / sizeof(*gHandlers); ++h)
{
if (aMessage == h->mMessage)
{
return h->mHandler(aWindow, aWparam, aLparam);
}
}
return DefWindowProc(aWindow, aMessage, aWparam, aLparam);
};
VERIFY(RegisterClass(&wc));
auto hwnd = CreateWindow(wc.lpszClassName,
TEXT("Lesson3.2-Demo Desktop Window Skeleton"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP,
nullptr, hInstance, nullptr);
ASSERT(hwnd);
MSG message = {};
BOOL result = FALSE;
while (0 != (result = GetMessage(&message, HWND_DESKTOP, 0, 0)))
{
if (-1 != result)
{
DispatchMessage(&message);
}
}
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Precompiled.h"
#include <tchar.h>
//#include <atlbase.h> //TODO: Do not avalible on Express Edition
//#include <atlwin.h> //TODO: Do not avalible on Express Edition
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hInstance;
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
//MSG message = {};
//BOOL result = FALSE;
//while (result = GetMessage(&message, HWND_DESKTOP, 0, 0)) // TODO: While main functional not implemented,
//{ // TODO: see below comments why, this lines are comment for just exit from application
// if (-1 != result)
// {
// DispatchMessage(&message);
// }
//}
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Precompiled.h"
#include <tchar.h>
#if !defined(_WIN32_WINNT_WIN8) || _WIN32_WINNT < _WIN32_WINNT_WIN8
#include <d2d1.h> //For Vista, Seven
#elif _WIN32_WINNT > _WIN32_WINNT_WIN8 && _MSC_VER > 1700
#include <d2d1_2.h> // For Eight dot one
#else
#include <d2d1_1.h> // For Eight
#endif
#include <wrl.h>
static Microsoft::WRL::ComPtr<ID2D1Factory> gFactory = nullptr;
static Microsoft::WRL::ComPtr<ID2D1HwndRenderTarget> gTarget = nullptr;
void Create();
void CreateDeviceIndependentResources();
void CreateDeviceResources();
void Render(HWND aWindow, const RECT& aClientRect);
void Draw();
typedef LRESULT(* MessageCallback)(HWND, WPARAM, LPARAM);
struct MessageHandler
{
UINT mMessage;
MessageCallback mHandler;
};
static MessageHandler gHandlers[] =
{
{
WM_PAINT, [](HWND aWindow, WPARAM, LPARAM) -> LRESULT
{
PAINTSTRUCT ps;
VERIFY(BeginPaint(aWindow, &ps));
Render(aWindow, ps.rcPaint);
EndPaint(aWindow, &ps);
return 0;
}
},
{
WM_SIZE, [](HWND, WPARAM, LPARAM aLparam) -> LRESULT
{
if (gTarget)
{
if (S_OK != gTarget->Resize(D2D1::SizeU(LOWORD(aLparam), HIWORD(aLparam))))
{
gTarget.Reset();
}
}
return 0;
}
},
{
WM_DISPLAYCHANGE, [](HWND aWindow, WPARAM, LPARAM) -> LRESULT
{
VERIFY(InvalidateRect(aWindow, nullptr, false));
return 0;
}
},
{
WM_DESTROY, [](HWND, WPARAM, LPARAM) -> LRESULT
{
PostQuitMessage(0);
return 0;
}
}
};
void Create()
{
D2D1_FACTORY_OPTIONS fo = {};
#ifdef DEBUG
fo.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif
HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, fo,
gFactory.GetAddressOf()));
CreateDeviceIndependentResources();
}
void CreateDeviceIndependentResources()
{
}
void CreateDeviceResources()
{
}
void Render(HWND aWindow, const RECT& aClientRect)
{
if (!gTarget)
{
auto size = D2D1::SizeU(aClientRect.right - aClientRect.left,
aClientRect.bottom - aClientRect.top);
HR(gFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(aWindow, size), gTarget.GetAddressOf()));
CreateDeviceResources();
}
if (!(D2D1_WINDOW_STATE_OCCLUDED & gTarget->CheckWindowState()))
{
gTarget->BeginDraw();
Draw();
if (D2DERR_RECREATE_TARGET == gTarget->EndDraw())
{
gTarget.Reset();
}
}
}
void Draw()
{
gTarget->Clear(D2D1::ColorF(1.0f, 1.0f, 0.0f));
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Create();
WNDCLASS wc = {};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("Window");
wc.lpfnWndProc = [](HWND aWindow, UINT aMessage, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
for (auto h = gHandlers; h != gHandlers + sizeof(gHandlers) / sizeof(*gHandlers); ++h)
{
if (aMessage == h->mMessage)
{
return h->mHandler(aWindow, aWparam, aLparam);
}
}
return DefWindowProc(aWindow, aMessage, aWparam, aLparam);
};
VERIFY(RegisterClass(&wc));
auto hwnd = CreateWindow(wc.lpszClassName,
TEXT("Lesson3.7-Demo Creating the Factory and Render Target"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP,
nullptr, hInstance, nullptr);
ASSERT(hwnd);
MSG message = {};
BOOL result = FALSE;
while (0 != (result = GetMessage(&message, HWND_DESKTOP, 0, 0)))
{
if (-1 != result)
{
DispatchMessage(&message);
}
}
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1LinearGradientBrush> mBrush;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr)
{
}
void CreateDeviceResources()
{
D2D1_GRADIENT_STOP stops[] =
{
{ 0.0f, sColorWhite },
{ 1.0f, sColorBlue }
};
Microsoft::WRL::ComPtr<ID2D1GradientStopCollection> collection = nullptr;
HR(mTarget->CreateGradientStopCollection(stops, sizeof(stops) / sizeof(*stops),
D2D1_GAMMA_1_0/*D2D1_GAMMA_2_2*/,
D2D1_EXTEND_MODE_MIRROR/*D2D1_EXTEND_MODE_WRAP*//*D2D1_EXTEND_MODE_CLAMP*/,
collection.GetAddressOf()));
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = {};
HR(mTarget->CreateLinearGradientBrush(props, collection.Get(),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
auto size = mTarget->GetSize();
mBrush->SetEndPoint(D2D1::Point2F(size.width / 4.0f, size.height / 4.0f));
auto r = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
mTarget->FillRectangle(r, mBrush.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson4.10-Demo More about Gradient Stops"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1StrokeStyle> mStyle;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mStyle(nullptr)
{
}
void CreateDeviceIndependentResources()
{
D2D1_STROKE_STYLE_PROPERTIES props = {};
props.lineJoin = D2D1_LINE_JOIN_ROUND;
props.dashStyle = D2D1_DASH_STYLE_DASH_DOT;
props.dashCap = D2D1_CAP_STYLE_ROUND;
ASSERT(!mStyle);
HR(mFactory->CreateStrokeStyle(props, nullptr, 0, mStyle.GetAddressOf()));
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlue);
auto size = mTarget->GetSize();
auto r = D2D1::RectF(100.0f, 100.0f, size.width - 100.0f, size.height - 100.0f);
mTarget->DrawRectangle(r, mBrush.Get(), 20.0f, mStyle.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson4.12-Demo Different Strokes"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr)
{
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorBlue, mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlue);
auto size = mTarget->GetSize();
mBrush->SetOpacity(1.0f);
mBrush->SetColor(sColorBlack);
auto br = D2D1::RectF(100.0f, 100.0f, size.width - 100.0f, 200.0f);
mTarget->FillRectangle(br, mBrush.Get());
mBrush->SetColor(sColorWhite);
auto bw = D2D1::RectF(100.0f, 300.0f, size.width - 100.0f, 400.0f);
mTarget->FillRectangle(bw, mBrush.Get());
mBrush->SetOpacity(0.5f);
mBrush->SetColor(sColorYellow);
auto ry = D2D1::RectF(150.0f, 150.0f, size.width - 150.0f, 350.0f);
mTarget->FillRectangle(ry, mBrush.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson4.4-Demo Brushes"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1LinearGradientBrush> mBrush;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr)
{
}
void CreateDeviceResources()
{
D2D1_GRADIENT_STOP stops[] =
{
{ 0.0f, sColorWhite },
{ 1.0f, sColorBlue }
};
Microsoft::WRL::ComPtr<ID2D1GradientStopCollection> collection = nullptr;
HR(mTarget->CreateGradientStopCollection(stops, sizeof(stops) / sizeof(*stops),
collection.GetAddressOf()));
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = {};
HR(mTarget->CreateLinearGradientBrush(props, collection.Get(),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
auto size = mTarget->GetSize();
mBrush->SetEndPoint(D2D1::Point2F(size.width, size.height));
auto r = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
mTarget->FillRectangle(r, mBrush.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson4.6-Demo Linear Gradient Brush"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1RadialGradientBrush> mBrush;
void OnMouseMove(WORD aX, WORD aY)
{
if (mBrush)
{
//auto center = mBrush->GetCenter();
//mBrush->SetGradientOriginOffset(D2D1::Point2F(x - center.x, y - center.y));
mBrush->SetCenter(D2D1::Point2F(aX, aY));//
InvalidateRect(mWindow, nullptr, false);
}
}
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr)
{
sHandlers.push_back(MessageHandler(WM_MOUSEMOVE, [](HWND, WPARAM,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnMouseMove(x, y);
return 0;
}));
}
void CreateDeviceResources()
{
D2D1_GRADIENT_STOP stops[] =
{
{ 0.0f, sColorWhite },
{ 1.0f, sColorBlue }
};
Microsoft::WRL::ComPtr<ID2D1GradientStopCollection> collection = nullptr;
HR(mTarget->CreateGradientStopCollection(stops, sizeof(stops) / sizeof(*stops),
collection.GetAddressOf()));
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES props = {};
HR(mTarget->CreateRadialGradientBrush(props, collection.Get(),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
auto size = mTarget->GetSize();
//mBrush->SetCenter(D2D1::Point2F(size.width / 2.0f, size.height / 2.0f));
mBrush->SetRadiusX(size.width / 2.0f);
mBrush->SetRadiusY(size.height / 2.0f);
auto r = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
mTarget->FillRectangle(r, mBrush.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson4.8-Demo Radial Gradient Brush"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
//#include "Precompiled.h"
#include <windows.h>
#include <tchar.h>
#if _WIN32_WINNT < 0x0602
#include <d2d1.h> //For Vista, Seven
#else
#include <d2d1_1.h> // For Eight
#endif
#include <wrl.h>
#define TRACE(A) OutputDebugString(A);
#define HR(A) if FAILED(A) \
OutputDebugString(TEXT("Not S_OK\n"));
#define VERIFY(A) if(A == 0) OutputDebugString(TEXT("Function return zero\n"));
#define ASSERT(A) if(A == 0) DebugBreak();
static Microsoft::WRL::ComPtr<ID2D1Factory> gFactory = nullptr;
static Microsoft::WRL::ComPtr<ID2D1HwndRenderTarget> gTarget = nullptr;
static Microsoft::WRL::ComPtr<ID2D1RadialGradientBrush> gBrush = nullptr;
static const D2D1_COLOR_F gColorBlue = { 0.26f, 0.56f, 0.87f, 1.0f };
static const D2D1_COLOR_F gColorWhite = { 1.0f, 1.0f, 1.0f, 1.0f };
void Create();
void CreateDeviceIndependentResources();
void CreateDeviceResources();
void Render(HWND aWindow, const RECT& aClientRect);
void Draw();
typedef LRESULT(* messageCallback)(HWND, WPARAM, LPARAM);
struct MessageHandler
{
UINT mMessage;
messageCallback mHandler;
};
static MessageHandler gHandlers[] =
{
{
WM_PAINT, [](HWND aWindow, WPARAM, LPARAM) -> LRESULT
{
PAINTSTRUCT ps;
VERIFY(BeginPaint(aWindow, &ps));
Render(aWindow, ps.rcPaint);
EndPaint(aWindow, &ps);
return 0;
}
},
{
WM_SIZE, [](HWND, WPARAM, LPARAM aLparam) -> LRESULT
{
if (gTarget)
{
if (S_OK != gTarget->Resize(D2D1::SizeU(LOWORD(aLparam), HIWORD(aLparam))))
{
gTarget.Reset();
}
}
return 0;
}
},
{
WM_DISPLAYCHANGE, [](HWND aWindow, WPARAM, LPARAM aLparam) -> LRESULT
{
VERIFY(InvalidateRect(aWindow, nullptr, false));
return 0;
}
},
{
WM_MOUSEMOVE, [](HWND aWindow, WPARAM, LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
auto center = gBrush->GetCenter();
gBrush->SetGradientOriginOffset(D2D1::Point2F(x - center.x, y - center.y));
InvalidateRect(aWindow, nullptr, false);
return 0;
}
},
{
WM_DESTROY, [](HWND, WPARAM, LPARAM) -> LRESULT
{
PostQuitMessage(0);
return 0;
}
}
};
void Create()
{
D2D1_FACTORY_OPTIONS fo = {};
#ifdef DEBUG
fo.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif
HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, fo,
gFactory.GetAddressOf()));
CreateDeviceIndependentResources();
}
void CreateDeviceIndependentResources()
{
}
void CreateDeviceResources()
{
D2D1_GRADIENT_STOP stops[] =
{
{ 0.0f, gColorWhite },
{ 1.0f, gColorBlue }
};
Microsoft::WRL::ComPtr<ID2D1GradientStopCollection> collection = nullptr;
HR(gTarget->CreateGradientStopCollection(stops, sizeof(stops) / sizeof(*stops),
collection.GetAddressOf()));
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES props = {};
HR(gTarget->CreateRadialGradientBrush(props, collection.Get(),
gBrush.ReleaseAndGetAddressOf()));
}
void Render(HWND aWindow, const RECT& aClientRect)
{
if (!gTarget)
{
auto size = D2D1::SizeU(aClientRect.right - aClientRect.left,
aClientRect.bottom - aClientRect.top);
HR(gFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(aWindow, size), gTarget.GetAddressOf()));
CreateDeviceResources();
}
if (!(D2D1_WINDOW_STATE_OCCLUDED & gTarget->CheckWindowState()))
{
gTarget->BeginDraw();
Draw();
if (D2DERR_RECREATE_TARGET == gTarget->EndDraw())
{
gTarget.Reset();
}
}
}
void Draw()
{
auto size = gTarget->GetSize();
gBrush->SetCenter(D2D1::Point2F(size.width / 2.0f, size.height / 2.0f));
gBrush->SetRadiusX(size.width / 2.0f);
gBrush->SetRadiusY(size.height / 2.0f);
auto r = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
gTarget->FillRectangle(r, gBrush.Get());
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)lpCmdLine;
Create();
WNDCLASS wc = {};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("Window");
wc.lpfnWndProc = [](HWND aWindow, UINT aMessage, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
for (auto h = gHandlers; h != gHandlers + sizeof(gHandlers) / sizeof(*gHandlers); ++h)
{
if (aMessage == h->mMessage)
{
return h->mHandler(aWindow, aWparam, aLparam);
}
}
return DefWindowProc(aWindow, aMessage, aWparam, aLparam);
};
VERIFY(RegisterClass(&wc));
auto hwnd = CreateWindow(wc.lpszClassName, TEXT("Title"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP,
nullptr, hInstance, nullptr);
ASSERT(hwnd);
MSG message = {};
BOOL result = FALSE;
while (result = GetMessage(&message, HWND_DESKTOP, 0, 0))
{
if (-1 != result)
{
DispatchMessage(&message);
}
}
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> mPath;
D2D1_POINT_2F mC1;
D2D1_POINT_2F mC2;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mPath(nullptr),
mC1(), mC2()
{
}
void CreateDeviceIndependentResources()
{
ASSERT(!mPath);
HR(mFactory->CreatePathGeometry(mPath.GetAddressOf()));
Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink = nullptr;
HR(mPath->Open(sink.GetAddressOf()));
auto start = D2D1::Point2F(100.0f, 600.0f);
auto end = D2D1::Point2F(900.0f, 600.0f);
mC1 = D2D1::Point2F(50.0f, 50.0f);
mC2 = D2D1::Point2F(600.0f, 50.0f);
sink->BeginFigure(start, D2D1_FIGURE_BEGIN_FILLED);
sink->AddBezier(D2D1::BezierSegment(mC1, mC2, end));
sink->EndFigure(D2D1_FIGURE_END_OPEN);
sink->BeginFigure(start, D2D1_FIGURE_BEGIN_FILLED);
D2D1_QUADRATIC_BEZIER_SEGMENT quad[] =
{
{ { 400.0f, 0.0f }, { 400.0f, 300.0f } }, //{ mC1, end },
{ { 400.0f, 600.0f}, end } //{ mC2, start }
};
sink->AddQuadraticBeziers(quad, sizeof(quad) / sizeof(*quad));
sink->EndFigure(D2D1_FIGURE_END_OPEN/*D2D1_FIGURE_END_CLOSED*/);
HR(sink->Close());
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlue);
mTarget->FillEllipse(D2D1::Ellipse(mC1, 10.0f, 10.0f), mBrush.Get());
mTarget->FillEllipse(D2D1::Ellipse(mC2, 10.0f, 10.0f), mBrush.Get());
mTarget->DrawGeometry(mPath.Get(), mBrush.Get(), 20.0f);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson5.11-Demo Bezier Segments"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#define _USE_MATH_DEFINES
#include <cmath>
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
D2D1_POINT_2F EllipsePoint(const D2D1_ELLIPSE& aEllipse, float aAngle)
{
D2D1_POINT_2F point =
{
aEllipse.point.x + aEllipse.radiusX* std::cos(static_cast<float>(aAngle* M_PI / 180.0f)),
aEllipse.point.y + aEllipse.radiusY* std::sin(static_cast<float>(aAngle* M_PI / 180.0f))
};
return point;
}
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr)
{
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorBlue, mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlack); //mTarget->Clear(sColorBlue);
auto size = mTarget->GetSize();
auto offset = 50.0f;
//D2D1_RECT_F rect = { offset, offset, size.width - offset, size.height - offset };
//D2D1_ROUNDED_RECT rounded = { rect, 200.0f, 200.0f };
D2D1_POINT_2F center = { size.width / 2.0f, size.height / 2.0f };
D2D1_ELLIPSE ellipse = { center, center.x - offset, center.y - offset };
mBrush->SetColor(sColorWhite);
mTarget->FillEllipse(ellipse, mBrush.Get());
mBrush->SetColor(sColorRed);
mTarget->DrawEllipse(ellipse, mBrush.Get(), 40.0f);
mTarget->DrawLine(EllipsePoint(ellipse, 135.0f), EllipsePoint(ellipse, 315.0f),
mBrush.Get(), 40.0f);
/*mBrush->SetColor(sColorWhite);
mBrush->SetOpacity(1.0f);
mTarget->FillRectangle(rect, mBrush.Get());
mBrush->SetColor(sColorBlack);
mBrush->SetOpacity(0.5f);
mTarget->DrawRectangle(rect, mBrush.Get(), 20.0f);
mTarget->DrawRoundedRectangle(rounded, mBrush.Get(), 40.0f);
mBrush->SetColor(sColorYellow);
mTarget->DrawEllipse(ellipse, mBrush.Get(), 20.0f);*/
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson5.3-Demo Drawing and Filling Shapes"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> mRect;
Microsoft::WRL::ComPtr<ID2D1RoundedRectangleGeometry> mRounded;
Microsoft::WRL::ComPtr<ID2D1EllipseGeometry> mEllipse;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mRect(nullptr),
mRounded(nullptr), mEllipse(nullptr)
{
}
void CreateDeviceIndependentResources()
{
D2D1_RECT_F rect = { 100.0f, 100.0f, 600.0f, 400.0f };
D2D1_ROUNDED_RECT rounded = { rect, 40.0f, 40.0f };
D2D1_ELLIPSE ellipse =
{
{ 350.0f, 250.0f },
250.0, 150.0f
};
ASSERT(!mRect);
HR(mFactory->CreateRectangleGeometry(rect, mRect.GetAddressOf()));
ASSERT(!mRounded);
HR(mFactory->CreateRoundedRectangleGeometry(rounded, mRounded.GetAddressOf()));
ASSERT(!mEllipse);
HR(mFactory->CreateEllipseGeometry(ellipse, mEllipse.GetAddressOf()));
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
D2D1::BrushProperties(0.5f),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlue);
mTarget->DrawGeometry(mRect.Get(), mBrush.Get(), 40.0f);
mTarget->DrawGeometry(mRounded.Get(), mBrush.Get(), 50.0f);
mTarget->DrawGeometry(mEllipse.Get(), mBrush.Get(), 60.0f);
mTarget->FillGeometry(mEllipse.Get(), mBrush.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson5.5-Demo Simple Geometries"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> mPath;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mPath(nullptr)
{
}
void CreateDeviceIndependentResources()
{
ASSERT(!mPath);
HR(mFactory->CreatePathGeometry(mPath.GetAddressOf()));
Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink = nullptr;
HR(mPath->Open(sink.GetAddressOf()));
sink->BeginFigure(D2D1::Point2F(50.0f, 50.0f),
D2D1_FIGURE_BEGIN_HOLLOW/*D2D1_FIGURE_BEGIN_FILLED*/);
sink->AddLine(D2D1::Point2F(250.0f, 50.0f));
D2D1_POINT_2F points[] =
{
{ 250.0f, 250.0f },
{ 50.0f, 250.0f }
};
sink->AddLines(points, sizeof(points) / sizeof(*points));
sink->EndFigure(D2D1_FIGURE_END_CLOSED/*D2D1_FIGURE_END_OPEN*/);
sink->BeginFigure(D2D1::Point2F(300.0f, 100.0f), D2D1_FIGURE_BEGIN_FILLED);
D2D1_POINT_2F pg[] =
{
{ 500.0f, 100.0f },
{ 550.0f, 300.0f },
{ 350.0f, 300.0f }
};
sink->AddLines(pg, sizeof(pg) / sizeof(*pg));
sink->EndFigure(D2D1_FIGURE_END_CLOSED);
HR(sink->Close());
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
D2D1::BrushProperties(0.5f),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlue);
mBrush->SetColor(sColorYellow);
mTarget->FillGeometry(mPath.Get(), mBrush.Get());
mBrush->SetColor(sColorBlack);
mTarget->DrawGeometry(mPath.Get(), mBrush.Get(), 30.0f);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson5.7-Demo Path Geometries"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> mArc1;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> mArc2;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> mArc3;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> mArc4;
D2D1_POINT_2F mBegin;
D2D1_POINT_2F mEnd;
void BuildPath(Microsoft::WRL::ComPtr<ID2D1PathGeometry>& aPath,
D2D1_SWEEP_DIRECTION aDirection, D2D1_ARC_SIZE aSize)
{
D2D1_ARC_SEGMENT arc =
{
mEnd,
{ 200.0f, 200.0f },
0.0f,
aDirection,
aSize
};
HR(mFactory->CreatePathGeometry(aPath.ReleaseAndGetAddressOf()));
Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink = nullptr;
HR(aPath->Open(sink.GetAddressOf()));
sink->BeginFigure(mBegin, D2D1_FIGURE_BEGIN_FILLED);
sink->AddArc(arc);
sink->EndFigure(D2D1_FIGURE_END_OPEN);
HR(sink->Close());
}
void BuildPaths()
{
BuildPath(mArc1, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, D2D1_ARC_SIZE_LARGE);
BuildPath(mArc2, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, D2D1_ARC_SIZE_SMALL);
BuildPath(mArc3, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_LARGE);
BuildPath(mArc4, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL);
}
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption),
mBrush(nullptr),
mArc1(nullptr),
mArc2(nullptr),
mArc3(nullptr),
mArc4(nullptr),
mBegin(),
mEnd()
{
sHandlers.push_back(MessageHandler(WM_MOUSEMOVE, [](HWND, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnMouseMove(x, y, aWparam);
return 0;
}));
}
void CreateDeviceIndependentResources()
{
mBegin = D2D1::Point2F(400.0f, 200.0f);
mEnd = D2D1::Point2F(600.0f, 500.0f);
BuildPaths();
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorYellow, D2D1::BrushProperties(0.7f),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorWhite);
mBrush->SetColor(sColorYellow);
mTarget->FillEllipse(D2D1::Ellipse(mBegin, 50.0f, 50.0f), mBrush.Get());
mBrush->SetColor(sColorGreen);
mTarget->FillEllipse(D2D1::Ellipse(mEnd, 50.0f, 50.0f), mBrush.Get());
mBrush->SetColor(sColorBlack);
mTarget->DrawGeometry(mArc1.Get(), mBrush.Get(), 50.0f);
mTarget->DrawGeometry(mArc2.Get(), mBrush.Get(), 50.0f);
mBrush->SetColor(sColorBlue);
mTarget->DrawGeometry(mArc3.Get(), mBrush.Get(), 50.0f);
mTarget->DrawGeometry(mArc4.Get(), mBrush.Get(), 50.0f);
}
void MoveBegin(float aX, float aY)
{
mBegin = D2D1::Point2F(aX, aY);
BuildPaths();
InvalidateRect(mWindow, nullptr, false);
}
void MoveEnd(float aX, float aY)
{
mEnd = D2D1::Point2F(aX, aY);
BuildPaths();
InvalidateRect(mWindow, nullptr, false);
}
void OnMouseMove(float aX, float aY, WPARAM aKeys)
{
if (MK_LBUTTON & aKeys)
{
MoveBegin(aX, aY);
}
if (MK_RBUTTON & aKeys)
{
MoveEnd(aX, aY);
}
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson5.9-Demo Arc Segments"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
#include <wincodec.h>
static wchar_t gImageFilePath[MAX_PATH];
struct ComInitialze
{
ComInitialze()
{
HR(CoInitialize(nullptr));
}
~ComInitialze()
{
CoUninitialize();
}
};
template <typename T>
void CreateInstance(REFCLSID aClsid, Microsoft::WRL::ComPtr<T>& aPtr)
{
ASSERT(!aPtr);
HR(CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER,
__uuidof(T), reinterpret_cast<void**>(aPtr.GetAddressOf())));
}
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<IWICFormatConverter> mImage;
Microsoft::WRL::ComPtr<ID2D1Bitmap> mBitmap;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mImage(nullptr), mBitmap(nullptr)
{
}
void CreateDeviceIndependentResources()
{
Microsoft::WRL::ComPtr<IWICImagingFactory> imageFactory = nullptr;
CreateInstance(CLSID_WICImagingFactory, imageFactory);
Microsoft::WRL::ComPtr<IWICBitmapDecoder> decoder = nullptr;
HR(imageFactory->CreateDecoderFromFilename(
gImageFilePath, nullptr,
GENERIC_READ, WICDecodeMetadataCacheOnLoad, decoder.GetAddressOf()));
Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> frame = nullptr;
HR(decoder->GetFrame(0, frame.GetAddressOf()));
ASSERT(!mImage);
HR(imageFactory->CreateFormatConverter(mImage.GetAddressOf()));
HR(mImage->Initialize(frame.Get(), GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone, nullptr, 0.0,
WICBitmapPaletteTypeCustom));
}
void CreateDeviceResources()
{
HR(mTarget->CreateBitmapFromWicBitmap(mImage.Get(),
mBitmap.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorWhite);
auto size = mTarget->GetSize();
auto rect = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
mTarget->DrawBitmap(mBitmap.Get(), rect, 1.0f,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)nCmdShow;
if (lpCmdLine && lstrlen(lpCmdLine))
{
#if UNICODE
memcpy(gImageFilePath, lpCmdLine, sizeof(gImageFilePath));
#else
MultiByteToWideChar(CP_ACP, 0, lpCmdLine, lstrlen(lpCmdLine), gImageFilePath,
sizeof(gImageFilePath) / sizeof(*gImageFilePath));
#endif
ComInitialze com;
Sample s(hInstance, TEXT("Lesson6.3-Demo Loading and Drawing Bitmaps"));
s.Run();
}
else
{
MessageBox(nullptr, TEXT("Path to picture must be pass through command line."),
TEXT("App failed to start"), MB_ICONWARNING);
return -1;
}
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
#include <wincodec.h>
static wchar_t gImageFilePath[MAX_PATH];
struct ComInitialze
{
ComInitialze()
{
HR(CoInitialize(nullptr));
}
~ComInitialze()
{
CoUninitialize();
}
};
template <typename T>
void CreateInstance(REFCLSID aClsid, Microsoft::WRL::ComPtr<T>& aPtr)
{
ASSERT(!aPtr);
HR(CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER,
__uuidof(T), reinterpret_cast<void**>(aPtr.GetAddressOf())));
}
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<IWICFormatConverter> mImage;
Microsoft::WRL::ComPtr<ID2D1BitmapBrush> mBrush;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mImage(nullptr), mBrush(nullptr)
{
}
void CreateDeviceIndependentResources()
{
Microsoft::WRL::ComPtr<IWICImagingFactory> imageFactory = nullptr;
CreateInstance(CLSID_WICImagingFactory, imageFactory);
Microsoft::WRL::ComPtr<IWICBitmapDecoder> decoder = nullptr;
HR(imageFactory->CreateDecoderFromFilename(
gImageFilePath, nullptr,
GENERIC_READ, WICDecodeMetadataCacheOnLoad, decoder.GetAddressOf()));
Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> frame = nullptr;
HR(decoder->GetFrame(0, frame.GetAddressOf()));
ASSERT(!mImage);
HR(imageFactory->CreateFormatConverter(mImage.GetAddressOf()));
HR(mImage->Initialize(frame.Get(), GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone, nullptr, 0.0,
WICBitmapPaletteTypeCustom));
}
void CreateDeviceResources()
{
Microsoft::WRL::ComPtr<ID2D1Bitmap> bitmap = nullptr;
HR(mTarget->CreateBitmapFromWicBitmap(mImage.Get(),
bitmap.GetAddressOf()));
HR(mTarget->CreateBitmapBrush(bitmap.Get(), mBrush.ReleaseAndGetAddressOf()));
//mBrush->SetExtendModeY(D2D1_EXTEND_MODE_MIRROR/*D2D1_EXTEND_MODE_WRAP*/);
mBrush->SetExtendModeX(D2D1_EXTEND_MODE_MIRROR);
mBrush->SetExtendModeY(D2D1_EXTEND_MODE_MIRROR);
}
void Draw()
{
mTarget->Clear(sColorWhite);
auto size = mTarget->GetSize();
auto rect = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
mTarget->FillRectangle(rect, mBrush.Get());
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)nCmdShow;
if (lpCmdLine && lstrlen(lpCmdLine))
{
#if UNICODE
memcpy(gImageFilePath, lpCmdLine, sizeof(gImageFilePath));
#else
MultiByteToWideChar(CP_ACP, 0, lpCmdLine, lstrlen(lpCmdLine), gImageFilePath,
sizeof(gImageFilePath) / sizeof(*gImageFilePath));
#endif
ComInitialze com;
Sample s(hInstance, TEXT("Lesson6.5-Demo Bitmap Brushes"));
s.Run();
}
else
{
MessageBox(nullptr, TEXT("Path to picture must be pass through command line."),
TEXT("App failed to start"), MB_ICONWARNING);
return -1;
}
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Precompiled.h"
#include <shlwapi.h>
#include <tchar.h>
#if !defined(_WIN32_WINNT_WIN8) || _WIN32_WINNT < _WIN32_WINNT_WIN8
#include <d2d1.h> //For Vista, Seven
#elif _WIN32_WINNT > _WIN32_WINNT_WIN8 && _MSC_VER > 1700
#include <d2d1_2.h> // For Eight dot one
#else
#include <d2d1_1.h> // For Eight
#endif
#include <wrl.h>
#include <wincodec.h>
#pragma comment(lib, "Shlwapi.lib")
static const D2D1_COLOR_F gColorBlue = { 0.26f, 0.56f, 0.87f, 1.0f };
struct ComInitialze
{
ComInitialze()
{
HR(CoInitialize(nullptr));
}
~ComInitialze()
{
CoUninitialize();
}
};
template <typename T>
void CreateInstance(REFCLSID aClsid, Microsoft::WRL::ComPtr<T>& aPtr)
{
ASSERT(!aPtr);
HR(CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER,
__uuidof(T), reinterpret_cast<void**>(aPtr.GetAddressOf())));
}
void SaveAs(Microsoft::WRL::ComPtr<IWICImagingFactory>& aImageFactory,
Microsoft::WRL::ComPtr<IWICBitmap>& aBitmap,
PCWSTR aFileName)
{
Microsoft::WRL::ComPtr<IStream> file = nullptr;
HR(SHCreateStreamOnFileEx(aFileName,
STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
FILE_ATTRIBUTE_NORMAL,
TRUE,
nullptr,
file.GetAddressOf()));
Microsoft::WRL::ComPtr<IWICBitmapEncoder> encoder = nullptr;
HR(aImageFactory->CreateEncoder(GUID_ContainerFormatPng,
nullptr, encoder.GetAddressOf()));
HR(encoder->Initialize(file.Get(), WICBitmapEncoderNoCache));
Microsoft::WRL::ComPtr<IWICBitmapFrameEncode> frame = nullptr;
Microsoft::WRL::ComPtr<IPropertyBag2> properties = nullptr;
HR(encoder->CreateNewFrame(frame.GetAddressOf(), properties.GetAddressOf()));
HR(frame->Initialize(properties.Get()));
UINT width = 0;
UINT height = 0;
HR(aBitmap->GetSize(&width, &height));
HR(frame->SetSize(width, height));
GUID pixelFormat = GUID_NULL;
HR(aBitmap->GetPixelFormat(&pixelFormat));
auto negotiated = pixelFormat;
HR(frame->SetPixelFormat(&negotiated));
HR(frame->WriteSource(aBitmap.Get(), nullptr));
HR(frame->Commit());
HR(encoder->Commit());
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hInstance;
(void)hPrevInstance;
(void)nCmdShow;
if (!lpCmdLine || !lstrlen(lpCmdLine))
{
MessageBox(nullptr,
TEXT("Path where to save picture must be pass through command line."),
TEXT("App failed to start"), MB_ICONWARNING);
return -1;
}
wchar_t imageFilePath[MAX_PATH] = {};
#if UNICODE
memcpy(imageFilePath, lpCmdLine, sizeof(imageFilePath));
#else
MultiByteToWideChar(CP_ACP, 0, lpCmdLine, lstrlen(lpCmdLine), imageFilePath,
sizeof(imageFilePath) / sizeof(*imageFilePath));
#endif
ComInitialze com;
D2D1_FACTORY_OPTIONS fo = {};
#ifdef DEBUG
fo.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif
Microsoft::WRL::ComPtr<ID2D1Factory> factory = nullptr;
HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, fo,
factory.GetAddressOf()));
Microsoft::WRL::ComPtr<IWICImagingFactory> imageFactory = nullptr;
CreateInstance(CLSID_WICImagingFactory, imageFactory);
Microsoft::WRL::ComPtr<IWICBitmap> bitmap = nullptr;
HR(imageFactory->CreateBitmap(640, 480,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapCacheOnLoad,
bitmap.GetAddressOf()));
Microsoft::WRL::ComPtr<ID2D1RenderTarget> target = nullptr;
HR(factory->CreateWicBitmapRenderTarget(bitmap.Get(),
D2D1::RenderTargetProperties(), target.GetAddressOf()));
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> brush = nullptr;
HR(target->CreateSolidColorBrush(gColorBlue, brush.GetAddressOf()));
target->BeginDraw();
target->Clear();
target->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(300.0f, 200.0f), 100.0f,
100.0f),
brush.Get(), 50.0f);
HR(target->EndDraw());
SaveAs(imageFactory, bitmap, imageFilePath);
ShellExecute(nullptr, nullptr, lpCmdLine, nullptr, nullptr, SW_SHOWDEFAULT);
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> mGeometry;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mGeometry(nullptr)
{
}
void CreateDeviceIndependentResources()
{
auto rect = D2D1::RectF(0.0f, 0.0f, 100.0f, 100.0f);
ASSERT(!mGeometry);
HR(mFactory->CreateRectangleGeometry(rect, mGeometry.GetAddressOf()));
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
D2D1::BrushProperties(0.7f),
mBrush.ReleaseAndGetAddressOf()));
}
void DrawGeometry(const D2D1_COLOR_F& aColor)
{
mBrush->SetColor(aColor);
mTarget->FillGeometry(mGeometry.Get(), mBrush.Get());
}
void Draw()
{
mTarget->Clear(sColorBlue);
mTarget->SetTransform(D2D1::Matrix3x2F::Identity());
DrawGeometry(sColorBlack);
auto t = D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorWhite);
t = t * D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorYellow);
auto scale = D2D1::Matrix3x2F::Scale(2.0f, 2.0f);
auto rotation = D2D1::Matrix3x2F::Rotation(45.0f, D2D1::Point2F(100.0f,
100.0f));
//auto skew = D2D1::Matrix3x2F::Skew(45.0f, 0.0f);
//mTarget->SetTransform(skew * t);
//DrawGeometry(sColorRed);
auto skew = D2D1::Matrix3x2F::Skew(45.0f, -45.0f, D2D1::Point2F(50.0f, 50.0f));
mTarget->SetTransform(skew * t);
DrawGeometry(sColorRed);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson7.10-Demo Skew"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
#define D2D1_Version1dot1 defined(_WIN32_WINNT_WIN8) && _WIN32_WINNT >= _WIN32_WINNT_WIN8
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> mGeometry;
#if D2D1_Version1dot1
Microsoft::WRL::ComPtr<ID2D1StrokeStyle1> mStyle;
#endif
D2D1_POINT_2F mOffset;
D2D1_POINT_2F mAnchor;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption),
mBrush(nullptr),
mGeometry(nullptr),
#if D2D1_Version1dot1
mStyle(nullptr),
#endif
mOffset(),
mAnchor()
{
sHandlers.push_back(MessageHandler(WM_LBUTTONDOWN, [](HWND, WPARAM,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnLeftMouseButtonDown(x, y);
return 0;
}));
sHandlers.push_back(MessageHandler(WM_MOUSEMOVE, [](HWND, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnMouseMove(x, y, aWparam);
return 0;
}));
}
void CreateDeviceIndependentResources()
{
auto rect = D2D1::RectF(0.0f, 0.0f, 100.0f, 100.0f);
ASSERT(!mGeometry);
HR(mFactory->CreateRectangleGeometry(rect, mGeometry.GetAddressOf()));
mOffset = D2D1::Point2F(1.0f, 1.0f);
mAnchor = D2D1::Point2F();
#if D2D1_Version1dot1
D2D1_STROKE_STYLE_PROPERTIES1 props = {};
props.miterLimit = 10.0f;
props.transformType = D2D1_STROKE_TRANSFORM_TYPE_FIXED;
ASSERT(!mStyle);
HR(mFactory->CreateStrokeStyle(props, nullptr, 0, mStyle.GetAddressOf()));
#endif
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorBlue);
auto t = D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
auto scale = D2D1::Matrix3x2F::Scale(max(1.0f, mOffset.x),
max(1.0f, mOffset.y));
#if D2D1_Version1dot1
mTarget->SetTransform(scale * t);
mTarget->DrawGeometry(mGeometry.Get(), mBrush.Get(), 5.0f, mStyle.Get());
#else
Microsoft::WRL::ComPtr<ID2D1TransformedGeometry> geometry = nullptr;
HR(mFactory->CreateTransformedGeometry(mGeometry.Get(),
scale * t, geometry.GetAddressOf()));
mTarget->DrawGeometry(geometry.Get(), mBrush.Get(), 5.0f);
#endif
}
void OnLeftMouseButtonDown(float aX, float aY)
{
mAnchor.x = aX;
mAnchor.y = aY;
}
void OnMouseMove(float aX, float aY, WPARAM aKeys)
{
if (MK_LBUTTON & aKeys)
{
mOffset.x = 1 + (aX - mAnchor.x) / 100.0f;
mOffset.y = 1 + (aY - mAnchor.y) / 100.0f;
InvalidateRect(mWindow, nullptr, false);
}
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson7.12-Demo Transforming Geometries"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1LinearGradientBrush> mBrush;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr)
{
sHandlers.push_back(MessageHandler(WM_MOUSEMOVE, [](HWND, WPARAM,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnMouseMove(x, y);
return 0;
}));
}
void CreateDeviceIndependentResources()
{
}
void CreateDeviceResources()
{
D2D1_GRADIENT_STOP stops[] =
{
{ 0.0f, sColorWhite },
{ 1.0f, sColorBlue }
};
Microsoft::WRL::ComPtr<ID2D1GradientStopCollection> collection = nullptr;
HR(mTarget->CreateGradientStopCollection(stops, sizeof(stops) / sizeof(*stops),
collection.GetAddressOf()));
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = {};
HR(mTarget->CreateLinearGradientBrush(props, collection.Get(),
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
auto size = mTarget->GetSize();
mBrush->SetEndPoint(D2D1::Point2F(size.width, size.height));
auto r = D2D1::RectF(0.0f, 0.0f, size.width, size.height);
mTarget->FillRectangle(r, mBrush.Get());
}
void OnMouseMove(float aX, float aY)
{
if (mTarget && mBrush)
{
auto size = mTarget->GetSize();
auto t = D2D1::Matrix3x2F::Translation(aX - size.width, aY - size.height);
mBrush->SetTransform(t);
InvalidateRect(mWindow, nullptr, false);
}
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson7.14-Demo Transforming Brushes"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> mGeometry;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mGeometry(nullptr)
{
}
void CreateDeviceIndependentResources()
{
auto rect = D2D1::RectF(0.0f, 0.0f, 100.0f, 100.0f);
ASSERT(!mGeometry);
HR(mFactory->CreateRectangleGeometry(rect, mGeometry.GetAddressOf()));
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
mBrush.ReleaseAndGetAddressOf()));
}
void DrawGeometry(const D2D1_COLOR_F& aColor)
{
mBrush->SetColor(aColor);
mTarget->FillGeometry(mGeometry.Get(), mBrush.Get());
}
void Draw()
{
mTarget->Clear(sColorBlue);
mTarget->SetTransform(D2D1::Matrix3x2F::Identity());
DrawGeometry(sColorBlack);
auto t = D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorWhite);
t = t * D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorYellow);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson7.4-Demo Translation"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> mGeometry;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mGeometry(nullptr)
{
}
void CreateDeviceIndependentResources()
{
auto rect = D2D1::RectF(0.0f, 0.0f, 100.0f, 100.0f);
ASSERT(!mGeometry);
HR(mFactory->CreateRectangleGeometry(rect, mGeometry.GetAddressOf()));
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
mBrush.ReleaseAndGetAddressOf()));
}
void DrawGeometry(const D2D1_COLOR_F& aColor)
{
mBrush->SetColor(aColor);
mTarget->FillGeometry(mGeometry.Get(), mBrush.Get());
}
void Draw()
{
mTarget->Clear(sColorBlue);
mTarget->SetTransform(D2D1::Matrix3x2F::Identity());
DrawGeometry(sColorBlack);
auto t = D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorWhite);
t = t * D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorYellow);
t = D2D1::Matrix3x2F::Scale(1.8f,
1.8f) * t; // t * D2D1::Matrix3x2F::Scale(1.8f, 1.8f)
mTarget->SetTransform(t);
DrawGeometry(sColorRed);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson7.6-Demo Scale"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> mGeometry;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption), mBrush(nullptr), mGeometry(nullptr)
{
}
void CreateDeviceIndependentResources()
{
auto rect = D2D1::RectF(0.0f, 0.0f, 100.0f, 100.0f);
ASSERT(!mGeometry);
HR(mFactory->CreateRectangleGeometry(rect, mGeometry.GetAddressOf()));
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorWhite,
D2D1::BrushProperties(0.7f),
mBrush.ReleaseAndGetAddressOf()));
}
void DrawGeometry(const D2D1_COLOR_F& aColor)
{
mBrush->SetColor(aColor);
mTarget->FillGeometry(mGeometry.Get(), mBrush.Get());
}
void Draw()
{
mTarget->Clear(sColorBlue);
mTarget->SetTransform(D2D1::Matrix3x2F::Identity());
DrawGeometry(sColorBlack);
auto t = D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorWhite);
t = t * D2D1::Matrix3x2F::Translation(50.0f, 50.0f);
mTarget->SetTransform(t);
DrawGeometry(sColorYellow);
auto scale = D2D1::Matrix3x2F::Scale(2.0f, 2.0f);
auto rotation = D2D1::Matrix3x2F::Rotation(45.0f, D2D1::Point2F(100.0f,
100.0f));//D2D1::Matrix3x2F::Rotation(45.0f, D2D1::Point2F(50.0f, 50.0f));//D2D1::Matrix3x2F::Rotation(45.0f);
mTarget->SetTransform(scale * rotation *
t);//mTarget->SetTransform(rotation * scale * t);
DrawGeometry(sColorRed);
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Sample s(hInstance, TEXT("Lesson7.8-Demo Rotation"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#include "Library.h"
#if !defined(_WIN32_WINNT_WIN8) || _WIN32_WINNT < _WIN32_WINNT_WIN8
#include <dwrite.h> //For Vista, Seven
#elif _WIN32_WINNT > _WIN32_WINNT_WIN8 && _MSC_VER > 1700
#include <dwrite_2.h> // For Eight dot one
#else
#include <dwrite_1.h> // For Eight
#endif
#pragma comment(lib, "dwrite.lib")
static TCHAR gImageFilePath[MAX_PATH];
class UnicodeFile
{
private:
PCWSTR mView;
UINT32 mSize;
public:
UnicodeFile(TCHAR* aFileName) : mView(nullptr), mSize(0)
{
auto file = CreateFile(aFileName, GENERIC_READ, FILE_SHARE_READ, nullptr,
OPEN_EXISTING, 0, nullptr);
ASSERT(file);
LARGE_INTEGER size = {};
VERIFY(GetFileSizeEx(file, &size));
mSize = static_cast<UINT32>(size.QuadPart / sizeof(WCHAR));
auto map = CreateFileMapping(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
ASSERT(map);
VERIFY(CloseHandle(file));
mView = static_cast<PCWSTR>(MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0));
ASSERT(mView);
VERIFY(CloseHandle(map));
}
~UnicodeFile()
{
VERIFY(UnmapViewOfFile(mView));
}
PCWSTR text() const
{
ASSERT(mView);
return mView;
}
UINT32 size() const
{
return mSize;
}
};
class Sample : public Win32Direct2D<Sample>
{
public:
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mBrush;
Microsoft::WRL::ComPtr<IDWriteTextLayout> mTextLayout;
float mOffset;
float mAnchor;
Sample(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: Win32Direct2D(aHinstance, aWindowCaption),
mBrush(nullptr),
mTextLayout(nullptr),
mOffset(0.0f),
mAnchor(0.0f)
{
sHandlers.push_back(MessageHandler(WM_LBUTTONDOWN, [](HWND, WPARAM,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnLeftMouseButtonDown(x, y);
return 0;
}));
sHandlers.push_back(MessageHandler(WM_MOUSEMOVE, [](HWND, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
WORD x = LOWORD(aLparam);
WORD y = HIWORD(aLparam);
Win32Direct2D::sWin32Direct2D->OnMouseMove(x, y, aWparam);
return 0;
}));
}
void CreateDeviceIndependentResources()
{
Microsoft::WRL::ComPtr<IDWriteFactory> textFactory = nullptr;
HR(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
__uuidof(textFactory), reinterpret_cast<IUnknown**>
(textFactory.GetAddressOf())));
Microsoft::WRL::ComPtr<IDWriteTextFormat> textFormat = nullptr;
HR(textFactory->CreateTextFormat(L"Candara",
nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, 30.0f, L"", textFormat.GetAddressOf()));
//HR(textFormat->SetReadingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT));
UnicodeFile file(gImageFilePath);
ASSERT(!mTextLayout);
HR(textFactory->CreateTextLayout(file.text(), file.size(), textFormat.Get(),
100.0f, 100.0f,
mTextLayout.GetAddressOf()));
mOffset = 0.0f;
}
void OnLeftMouseButtonDown(float, float aY)
{
mAnchor = aY - mOffset;
}
void OnMouseMove(float, float aY, WPARAM aKeys)
{
if (MK_LBUTTON & aKeys)
{
mOffset = aY - mAnchor;
InvalidateRect(mWindow, nullptr, false);
}
}
void CreateDeviceResources()
{
HR(mTarget->CreateSolidColorBrush(sColorBlack,
mBrush.ReleaseAndGetAddressOf()));
}
void Draw()
{
mTarget->Clear(sColorWhite);
auto size = mTarget->GetSize();
auto margin = 50.0f;
size.width -= margin * 2.0f;
size.height -= margin * 2.0f;
if (S_OK == mTextLayout->SetMaxWidth(size.width) &&
S_OK == mTextLayout->SetMaxHeight(size.height))
{
auto t = D2D1::Matrix3x2F::Translation(0.0f, min(0.0f, mOffset));
mTarget->SetTransform(t);
mTarget->DrawTextLayout(D2D1::Point2F(margin, margin),
mTextLayout.Get(), mBrush.Get(),
D2D1_DRAW_TEXT_OPTIONS_NONE);
}
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
(void)hPrevInstance;
(void)nCmdShow;
if (!lpCmdLine || !lstrlen(lpCmdLine))
{
MessageBox(nullptr,
TEXT("Path to UNICODE text file must be pass through command line."),
TEXT("App failed to start"), MB_ICONWARNING);
return -1;
}
memcpy(gImageFilePath, lpCmdLine, sizeof(gImageFilePath));
Sample s(hInstance, TEXT("Lesson8.3-Demo DirectWrite"));
s.Run();
return 0;
}
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#ifndef _LIBRARY_H_
#define _LIBRARY_H_
#include "Precompiled.h"
#include <tchar.h>
#if !defined(_WIN32_WINNT_WIN8) || _WIN32_WINNT < _WIN32_WINNT_WIN8
#include <d2d1.h> //For Vista, Seven
#elif _WIN32_WINNT > _WIN32_WINNT_WIN8 && _MSC_VER > 1700
#include <d2d1_2.h> // For Eight dot one
#else
#include <d2d1_1.h> // For Eight
#endif
#include <wrl.h>
#include <vector>
typedef LRESULT(* MessageCallback)(HWND, WPARAM, LPARAM);
struct MessageHandler
{
UINT mMessage;
MessageCallback mHandler;
MessageHandler(UINT aMessage, MessageCallback aHandler) : mMessage(aMessage),
mHandler(aHandler)
{
}
};
template<typename T>
class Win32Direct2D
{
public:
Win32Direct2D(HINSTANCE aHinstance, TCHAR* aWindowCaption);
virtual void Run();
virtual void Create();
virtual void CreateDeviceIndependentResources();
virtual void CreateDeviceResources();
virtual void Render(const RECT& aClientRect);
virtual void Draw();
virtual void OnSizeChanged(WORD aWidth, WORD aHeight);
static T* sWin32Direct2D;
static const D2D1_COLOR_F sColorBlue;
static const D2D1_COLOR_F sColorYellow;
static const D2D1_COLOR_F sColorRed;
static const D2D1_COLOR_F sColorGreen;
static const D2D1_COLOR_F sColorBlack;
static const D2D1_COLOR_F sColorWhite;
protected:
HWND mWindow;
HINSTANCE mHinstance;
TCHAR mWindowCaption[256];
Microsoft::WRL::ComPtr<ID2D1Factory> mFactory;
Microsoft::WRL::ComPtr<ID2D1HwndRenderTarget> mTarget;
static std::vector<MessageHandler> sHandlers;
};
#include "Library.inl"
#endif
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
template<typename T>
Win32Direct2D<T>::Win32Direct2D(HINSTANCE aHinstance, TCHAR* aWindowCaption)
: mWindow(HWND_DESKTOP), mHinstance(aHinstance)
{
memcpy(mWindowCaption, aWindowCaption, sizeof(mWindowCaption));
}
template<typename T>
void Win32Direct2D<T>::Run()
{
sWin32Direct2D = static_cast<T*>(this);
sWin32Direct2D->Create();
sHandlers.reserve(5);
sHandlers.push_back(MessageHandler(WM_PAINT, [](HWND aWindow, WPARAM,
LPARAM) -> LRESULT
{
PAINTSTRUCT ps;
VERIFY(BeginPaint(aWindow, &ps));
Win32Direct2D::sWin32Direct2D->Render(ps.rcPaint);
EndPaint(aWindow, &ps);
return 0;
}));
sHandlers.push_back(MessageHandler(WM_SIZE, [](HWND, WPARAM,
LPARAM aLparam) -> LRESULT
{
Win32Direct2D::sWin32Direct2D->OnSizeChanged(LOWORD(aLparam), HIWORD(aLparam));
return 0;
}));
sHandlers.push_back(MessageHandler(WM_DISPLAYCHANGE, [](HWND aWindow, WPARAM,
LPARAM) -> LRESULT
{
VERIFY(InvalidateRect(aWindow, nullptr, false));
return 0;
}));
sHandlers.push_back(MessageHandler(WM_DESTROY, [](HWND, WPARAM,
LPARAM) -> LRESULT
{
PostQuitMessage(0);
return 0;
}));
WNDCLASS wc = {};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hInstance = mHinstance;
wc.lpszClassName = TEXT("Window");
wc.lpfnWndProc = [](HWND aWindow, UINT aMessage, WPARAM aWparam,
LPARAM aLparam) -> LRESULT
{
for (auto h = sHandlers.begin(); h != sHandlers.end(); ++h)
{
if (aMessage == h->mMessage)
{
return h->mHandler(aWindow, aWparam, aLparam);
}
}
return DefWindowProc(aWindow, aMessage, aWparam, aLparam);
};
VERIFY(RegisterClass(&wc));
mWindow = CreateWindow(wc.lpszClassName,
mWindowCaption,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP,
nullptr, wc.hInstance, nullptr);
ASSERT(mWindow);
MSG message = {};
BOOL result = FALSE;
while (0 != (result = GetMessage(&message, HWND_DESKTOP, 0, 0)))
{
if (-1 != result)
{
DispatchMessage(&message);
}
}
}
template<typename T>
void Win32Direct2D<T>::Create()
{
D2D1_FACTORY_OPTIONS fo = {};
#ifdef DEBUG
fo.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif
HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, fo,
mFactory.GetAddressOf()));
sWin32Direct2D->CreateDeviceIndependentResources();
}
template<typename T>
void Win32Direct2D<T>::CreateDeviceIndependentResources()
{
}
template<typename T>
void Win32Direct2D<T>::CreateDeviceResources()
{
}
template<typename T>
void Win32Direct2D<T>::Render(const RECT& aClientRect)
{
if (!mTarget)
{
auto size = D2D1::SizeU(aClientRect.right - aClientRect.left,
aClientRect.bottom - aClientRect.top);
HR(mFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(mWindow, size), mTarget.GetAddressOf()));
sWin32Direct2D->CreateDeviceResources();
}
if (!(D2D1_WINDOW_STATE_OCCLUDED & mTarget->CheckWindowState()))
{
mTarget->BeginDraw();
sWin32Direct2D->Draw();
if (D2DERR_RECREATE_TARGET == mTarget->EndDraw())
{
mTarget.Reset();
}
}
}
template<typename T>
void Win32Direct2D<T>::Draw()
{
}
template<typename T>
void Win32Direct2D<T>::OnSizeChanged(WORD aWidth, WORD aHeight)
{
if (mTarget)
{
if (S_OK != mTarget->Resize(D2D1::SizeU(aWidth, aHeight)))
{
mTarget.Reset();
}
}
}
template<typename T>
T* Win32Direct2D<T>::sWin32Direct2D = nullptr;
template<typename T>
const D2D1_COLOR_F Win32Direct2D<T>::sColorBlue = { 0.26f, 0.56f, 0.87f, 1.0f };
template<typename T>
const D2D1_COLOR_F Win32Direct2D<T>::sColorYellow = { 0.99f, 0.85f, 0.0f, 1.0f };
template<typename T>
const D2D1_COLOR_F Win32Direct2D<T>::sColorRed = { 1.0f, 0.0f, 0.0f, 1.0f };
template<typename T>
const D2D1_COLOR_F Win32Direct2D<T>::sColorGreen = { 0.0f, 1.0f, 0.0f, 1.0f };
template<typename T>
const D2D1_COLOR_F Win32Direct2D<T>::sColorBlack = { 0.0f, 0.0f, 0.0f, 1.0f };
template<typename T>
const D2D1_COLOR_F Win32Direct2D<T>::sColorWhite = { 1.0f, 1.0f, 1.0f, 1.0f };
template<typename T>
std::vector<MessageHandler> Win32Direct2D<T>::sHandlers;
/*
(c) 2012 by Kenny Kerr, https://github.com/kennykerr
Original write for course "Pluralsight - Direct2D Fundamentals".
Edit while study.
*/
#ifndef _PRE_COMPILED_H_
#define _PRE_COMPILED_H_
#include <windows.h>
#define TRACE(A) OutputDebugString(A);
#define HR(A) if FAILED(A) \
OutputDebugString(TEXT("Not S_OK\n"));
#define VERIFY(A) if(A == 0) OutputDebugString(TEXT("Function return zero\n"));
#define ASSERT(A) if(A == 0) DebugBreak();
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment