diff --git a/project/Easy2D/Easy2D.vcxproj b/project/Easy2D/Easy2D.vcxproj
index a5a99d20..82024beb 100644
--- a/project/Easy2D/Easy2D.vcxproj
+++ b/project/Easy2D/Easy2D.vcxproj
@@ -51,6 +51,7 @@
     
     
     
+    
     
     
     
@@ -107,6 +108,7 @@
     
     
     
+    
     
     
     
diff --git a/project/Easy2D/Easy2D.vcxproj.filters b/project/Easy2D/Easy2D.vcxproj.filters
index 4ca70313..bed14fd0 100644
--- a/project/Easy2D/Easy2D.vcxproj.filters
+++ b/project/Easy2D/Easy2D.vcxproj.filters
@@ -229,6 +229,9 @@
     
       dx
     
+    
+      dx
+    
   
   
     
@@ -366,5 +369,8 @@
     
       dx
     
+    
+      dx
+    
   
 
\ No newline at end of file
diff --git a/src/core/Singleton.hpp b/src/core/Singleton.hpp
index c7f4b099..d5d630ff 100644
--- a/src/core/Singleton.hpp
+++ b/src/core/Singleton.hpp
@@ -43,7 +43,7 @@ namespace easy2d
 }
 
 // Class that will implement the singleton mode,
-// must use the macro in it's delare file
+// must use the macro in its delare file
 
 #ifndef E2D_DECLARE_SINGLETON
 #define E2D_DECLARE_SINGLETON( type )			\
diff --git a/src/core/config.h b/src/core/config.h
index cd378bfd..14a053df 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -21,3 +21,5 @@
 //#define E2D_API __declspec( dllexport )
 //#define E2D_API __declspec( dllimport )
 
+//---- Define DirectX version. Defaults to using Direct3D11
+//#define E2D_USE_DIRECTX10
diff --git a/src/core/modules.cpp b/src/core/modules.cpp
index 5bc4e84c..5292d6f4 100644
--- a/src/core/modules.cpp
+++ b/src/core/modules.cpp
@@ -42,42 +42,6 @@ namespace easy2d
 			}
 		}
 
-		DirectX::DirectX()
-		{
-			d2d = LoadLibraryW(L"d2d1.dll");
-			if (d2d)
-			{
-				D2D1CreateFactory = (PFN_D2D1CreateFactory)
-					GetProcAddress(d2d, "D2D1CreateFactory");
-			}
-			else
-			{
-				E2D_LOG(L"load d2d.dll failed");
-			}
-
-			dwrite = LoadLibraryW(L"dwrite.dll");
-			if (dwrite)
-			{
-				DWriteCreateFactory = (PFN_DWriteCreateFactory)
-					GetProcAddress(dwrite, "DWriteCreateFactory");
-			}
-			else
-			{
-				E2D_LOG(L"load dwrite.dll failed");
-			}
-
-			d3d11 = LoadLibraryW(L"d3d11.dll");
-			if (d3d11)
-			{
-				D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)
-					GetProcAddress(d3d11, "D3D11CreateDevice");
-			}
-			else
-			{
-				E2D_LOG(L"load d3d11.dll failed");
-			}
-		}
-
 		XAudio2::XAudio2()
 		{
 			const auto xaudio2_dll_names =
diff --git a/src/core/modules.h b/src/core/modules.h
index 998eee76..339d263f 100644
--- a/src/core/modules.h
+++ b/src/core/modules.h
@@ -20,13 +20,10 @@
 
 #pragma once
 #include "macros.h"
-#include 
-#include 
 #include 
 #include 
 #include 
 #include 
-#include 
 
 namespace easy2d
 {
@@ -54,31 +51,6 @@ namespace easy2d
 		};
 
 
-		class E2D_API DirectX
-		{
-			DirectX();
-
-			HMODULE d3d11;
-			HMODULE d2d;
-			HMODULE dwrite;
-
-			// DirectX functions
-			typedef HRESULT(WINAPI *PFN_D2D1CreateFactory)(D2D1_FACTORY_TYPE, const IID&, const D2D1_FACTORY_OPTIONS*, void **);
-			typedef HRESULT(WINAPI *PFN_DWriteCreateFactory)(DWRITE_FACTORY_TYPE, const IID&, IUnknown **);
-
-		public:
-			static DirectX& Get()
-			{
-				static DirectX instance;
-				return instance;
-			}
-
-			PFN_D2D1CreateFactory D2D1CreateFactory;
-			PFN_DWriteCreateFactory DWriteCreateFactory;
-			PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
-		};
-
-
 		class E2D_API XAudio2
 		{
 			XAudio2();
diff --git a/src/core/render.h b/src/core/render.h
index 79135d98..d7458d0b 100644
--- a/src/core/render.h
+++ b/src/core/render.h
@@ -28,8 +28,6 @@
 #include "../DX/DeviceResources.h"
 #include "../DX/TextRenderer.h"
 #include "time.h"
-#include 
-#include 
 
 namespace easy2d
 {
diff --git a/src/dx/D2DDeviceResources.cpp b/src/dx/D2DDeviceResources.cpp
index 78bfd705..821bab11 100644
--- a/src/dx/D2DDeviceResources.cpp
+++ b/src/dx/D2DDeviceResources.cpp
@@ -18,11 +18,14 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#include "DeviceResources.h"
+#include "D2DDeviceResources.h"
 #include "../core/Image.h"
 #include "../core/modules.h"
 #include "../core/logs.h"
 
+#pragma comment(lib, "d2d1.lib")
+#pragma comment(lib, "dwrite.lib")
+
 namespace easy2d
 {
 
@@ -106,7 +109,7 @@ namespace easy2d
 		options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
 #endif
 
-		hr = modules::DirectX::Get().D2D1CreateFactory(
+		hr = D2D1CreateFactory(
 			D2D1_FACTORY_TYPE_SINGLE_THREADED,
 			__uuidof(ID2D1Factory1),
 			&options,
@@ -117,7 +120,7 @@ namespace easy2d
 		{
 			d2d_factory_ = d2d_factory;
 
-			CoCreateInstance(
+			hr = CoCreateInstance(
 				CLSID_WICImagingFactory,
 				nullptr,
 				CLSCTX_INPROC_SERVER,
@@ -130,7 +133,7 @@ namespace easy2d
 		{
 			imaging_factory_ = imaging_factory;
 
-			modules::DirectX::Get().DWriteCreateFactory(
+			hr = DWriteCreateFactory(
 				DWRITE_FACTORY_TYPE_SHARED,
 				__uuidof(IDWriteFactory),
 				reinterpret_cast(&dwrite_factory)
diff --git a/src/dx/D2DDeviceResources.h b/src/dx/D2DDeviceResources.h
index e9555828..4eabae91 100644
--- a/src/dx/D2DDeviceResources.h
+++ b/src/dx/D2DDeviceResources.h
@@ -23,6 +23,7 @@
 #include "../core/Resource.h"
 #include "../core/Font.hpp"
 #include "../core/TextStyle.hpp"
+#include 
 #include 
 #include 
 
diff --git a/src/dx/D3D10DeviceResources.cpp b/src/dx/D3D10DeviceResources.cpp
new file mode 100644
index 00000000..3b0d4a4c
--- /dev/null
+++ b/src/dx/D3D10DeviceResources.cpp
@@ -0,0 +1,434 @@
+// Copyright (c) 2016-2018 Easy2D - Nomango
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "D3D10DeviceResources.h"
+
+#ifdef E2D_USE_DIRECTX10
+
+#include "../core/Image.h"
+#include "../core/logs.h"
+
+#pragma comment(lib, "d3d10_1.lib")
+
+namespace easy2d
+{
+#if defined(_DEBUG)
+	namespace DX
+	{
+		HRESULT CreateD3DDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, UINT flags, ID3D10Device1 **device)
+		{
+			HRESULT hr = S_OK;
+
+			static const D3D10_FEATURE_LEVEL1 levels[] =
+			{
+				D3D10_FEATURE_LEVEL_10_1,
+				D3D10_FEATURE_LEVEL_10_0,
+				D3D10_FEATURE_LEVEL_9_3,
+				D3D10_FEATURE_LEVEL_9_2,
+				D3D10_FEATURE_LEVEL_9_1,
+			};
+
+			for (UINT level = 0; level < ARRAYSIZE(levels); level++)
+			{
+				hr = D3D10CreateDevice1(
+					adapter,
+					driver_type,
+					NULL,
+					flags,
+					levels[level],
+					D3D10_1_SDK_VERSION,
+					device
+				);
+
+				if (SUCCEEDED(hr))
+					break;
+			}
+			return hr;
+		}
+
+		inline bool SdkLayersAvailable()
+		{
+			HRESULT hr = CreateD3DDevice(
+				NULL,
+				D3D10_DRIVER_TYPE_NULL,		// There is no need to create a real hardware device.
+				D3D10_CREATE_DEVICE_DEBUG,	// Check for the SDK layers.
+				nullptr						// No need to keep the D3D device reference.
+			);
+
+			return SUCCEEDED(hr);
+		}
+	}
+#endif
+
+	D3D10DeviceResources::D3D10DeviceResources()
+		: hwnd_(nullptr)
+	{
+		dpi_ = 96.f; // dpi_ = (float)GetDpiForWindow(hwnd);
+	}
+
+	D3D10DeviceResources::~D3D10DeviceResources()
+	{
+		DiscardResources();
+	}
+
+	HRESULT D3D10DeviceResources::Create(D3D10DeviceResources** device_resources, HWND hwnd)
+	{
+		HRESULT hr = E_FAIL;
+
+		if (device_resources)
+		{
+			D3D10DeviceResources* res = new (std::nothrow) D3D10DeviceResources;
+			if (res)
+			{
+				hr = res->CreateDeviceIndependentResources();
+
+				if (SUCCEEDED(hr))
+				{
+					RECT rc;
+					GetClientRect(hwnd, &rc);
+
+					res->hwnd_ = hwnd;
+					res->logical_size_.x = float(rc.right - rc.left);
+					res->logical_size_.y = float(rc.bottom - rc.top);
+
+					hr = res->CreateDeviceResources();
+				}
+
+				if (SUCCEEDED(hr))
+				{
+					hr = res->CreateWindowSizeDependentResources();
+				}
+
+				if (SUCCEEDED(hr))
+				{
+					res->AddRef();
+
+					DX::SafeRelease(*device_resources);
+					(*device_resources) = res;
+				}
+				else
+				{
+					delete res;
+					res = nullptr;
+				}
+			}
+		}
+		return hr;
+	}
+
+	void D3D10DeviceResources::DiscardResources()
+	{
+		d3d_device_.Reset();
+		d3d_rt_view_.Reset();
+		d3d_ds_view_.Reset();
+		dxgi_swap_chain_.Reset();
+		dxgi_factory_.Reset();
+
+		hwnd_ = nullptr;
+	}
+
+	HRESULT D3D10DeviceResources::CreateDeviceResources()
+	{
+		HRESULT hr = S_OK;
+
+		// This flag adds support for surfaces with a different color channel ordering
+		// than the API default. It is required for compatibility with Direct2D.
+		UINT creation_flags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
+
+#if defined(E2D_DEBUG)
+		if (DX::SdkLayersAvailable())
+		{
+			creation_flags |= D3D10_CREATE_DEVICE_DEBUG;
+		}
+#endif
+
+		ComPtr device;
+		hr = DX::CreateD3DDevice(
+			NULL,
+			D3D10_DRIVER_TYPE_HARDWARE,
+			creation_flags,
+			&device
+		);
+
+		if (SUCCEEDED(hr))
+		{
+			d3d_device_ = device;
+
+			ComPtr dxgi_adapter;
+			ComPtr dxgi_device;
+			ComPtr dxgi_factory;
+			ComPtr d2d_device;
+
+			if (SUCCEEDED(hr))
+			{
+				hr = d3d_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device));
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				hr = dxgi_device->GetAdapter(&dxgi_adapter);
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				dxgi_factory_ = dxgi_factory;
+			}
+
+			// Create the Direct2D device object and a corresponding context.
+			if (SUCCEEDED(hr))
+			{
+				hr = GetD2DFactory()->CreateDevice(dxgi_device.Get(), &d2d_device);
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				hr = SetD2DDevice(d2d_device);
+			}
+		}
+
+		if (SUCCEEDED(hr))
+		{
+			// Setup swap chain
+			DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
+
+			swap_chain_desc.BufferCount = 2;
+			swap_chain_desc.BufferDesc.Width = ::lround(output_size_.x);
+			swap_chain_desc.BufferDesc.Height = ::lround(output_size_.y);
+			swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+			swap_chain_desc.BufferDesc.RefreshRate.Numerator = 60;
+			swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1;
+			swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+			swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+			swap_chain_desc.OutputWindow = hwnd_;
+			swap_chain_desc.SampleDesc.Count = 1;
+			swap_chain_desc.SampleDesc.Quality = 0;
+			swap_chain_desc.Windowed = TRUE;
+			swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+			ComPtr dxgi_device;
+			if (SUCCEEDED(hr))
+			{
+				hr = d3d_device_->QueryInterface(&dxgi_device);
+			}
+
+			ComPtr dxgi_adapter;
+			if (SUCCEEDED(hr))
+			{
+				hr = dxgi_device->GetAdapter(&dxgi_adapter);
+			}
+
+			ComPtr dxgi_factory;
+			if (SUCCEEDED(hr))
+			{
+				hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				hr = dxgi_factory->CreateSwapChain(
+					d3d_device_.Get(),
+					&swap_chain_desc,
+					&dxgi_swap_chain_);
+			}
+		}
+
+		return hr;
+	}
+
+	HRESULT D3D10DeviceResources::CreateWindowSizeDependentResources()
+	{
+		if (!dxgi_swap_chain_)
+			return E_UNEXPECTED;
+
+		HRESULT hr = S_OK;
+
+		// Clear the previous window size specific context.
+		ID3D10RenderTargetView* null_views[] = { nullptr };
+		SetTargetBitmap(nullptr);
+		d3d_device_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
+		d3d_device_->Flush();
+
+		// Calculate the necessary render target size in pixels.
+		output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
+		output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
+
+		// Prevent zero size DirectX content from being created.
+		output_size_.x = std::max(output_size_.x, 1.f);
+		output_size_.y = std::max(output_size_.y, 1.f);
+
+		// If the swap chain already exists, resize it.
+		hr = dxgi_swap_chain_->ResizeBuffers(
+			2, // Double-buffered swap chain.
+			::lround(output_size_.x),
+			::lround(output_size_.y),
+			DXGI_FORMAT_B8G8R8A8_UNORM,
+			0);
+
+		if (SUCCEEDED(hr))
+		{
+			// Create the render target view and set it on the device
+			ComPtr dxgi_back_buffer;
+
+			hr = dxgi_swap_chain_->GetBuffer(
+				0,
+				IID_PPV_ARGS(&dxgi_back_buffer)
+			);
+
+			if (SUCCEEDED(hr))
+			{
+				D3D10_RENDER_TARGET_VIEW_DESC renderDesc;
+				renderDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+				renderDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
+				renderDesc.Texture2D.MipSlice = 0;
+
+				d3d_rt_view_ = nullptr;
+				hr = d3d_device_->CreateRenderTargetView(dxgi_back_buffer.Get(), &renderDesc, &d3d_rt_view_);
+			}
+
+			ComPtr depth_stencil;
+			if (SUCCEEDED(hr))
+			{
+				D3D10_TEXTURE2D_DESC tex_desc;
+				tex_desc.ArraySize = 1;
+				tex_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
+				tex_desc.CPUAccessFlags = 0;
+				tex_desc.Format = DXGI_FORMAT_D16_UNORM;
+				tex_desc.Width = static_cast(output_size_.x);
+				tex_desc.Height = static_cast(output_size_.y);
+				tex_desc.MipLevels = 1;
+				tex_desc.MiscFlags = 0;
+				tex_desc.SampleDesc.Count = 1;
+				tex_desc.SampleDesc.Quality = 0;
+				tex_desc.Usage = D3D10_USAGE_DEFAULT;
+
+				hr = d3d_device_->CreateTexture2D(&tex_desc, NULL, &depth_stencil);
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				D3D10_DEPTH_STENCIL_VIEW_DESC desc;
+				desc.Format = DXGI_FORMAT_D16_UNORM;
+				desc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
+				desc.Texture2D.MipSlice = 0;
+
+				d3d_ds_view_.Reset();
+				hr = d3d_device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &d3d_ds_view_);
+			}
+		}
+
+		if (SUCCEEDED(hr))
+		{
+			ID3D10RenderTargetView* views[] = { d3d_rt_view_.Get() };
+			d3d_device_->OMSetRenderTargets(1, views, d3d_ds_view_.Get());
+
+			// Set a new viewport based on the new dimensions
+			D3D10_VIEWPORT viewport;
+			viewport.Width = static_cast(output_size_.x);
+			viewport.Height = static_cast(output_size_.y);
+			viewport.TopLeftX = 0;
+			viewport.TopLeftY = 0;
+			viewport.MinDepth = 0;
+			viewport.MaxDepth = 1;
+
+			d3d_device_->RSSetViewports(1, &viewport);
+		}
+
+		// Create a Direct2D target bitmap associated with the
+		// swap chain back buffer and set it as the current target.
+		if (SUCCEEDED(hr))
+		{
+			ComPtr dxgi_back_buffer;
+			hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
+
+			ComPtr target;
+			if (SUCCEEDED(hr))
+			{
+				hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface(
+					dxgi_back_buffer.Get(),
+					D2D1::BitmapProperties1(
+						D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
+						D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
+						dpi_,
+						dpi_),
+					&target);
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				SetTargetBitmap(target);
+			}
+		}
+
+		return hr;
+	}
+
+	HRESULT D3D10DeviceResources::HandleDeviceLost()
+	{
+		dxgi_swap_chain_ = nullptr;
+
+		HRESULT hr = CreateDeviceResources();
+
+		if (SUCCEEDED(hr))
+		{
+			hr = CreateWindowSizeDependentResources();
+		}
+		return hr;
+	}
+
+	void D3D10DeviceResources::SetLogicalSize(Size logical_size)
+	{
+		if (logical_size_ != logical_size)
+		{
+			logical_size_ = logical_size;
+
+			ThrowIfFailed(
+				CreateWindowSizeDependentResources()
+			);
+		}
+	}
+
+	void D3D10DeviceResources::SetDpi(float dpi)
+	{
+		if (dpi != dpi_)
+		{
+			dpi_ = dpi;
+
+			RECT rc;
+			GetClientRect(hwnd_, &rc);
+
+			logical_size_.x = float(rc.right - rc.left);
+			logical_size_.y = float(rc.bottom - rc.top);
+
+			GetD2DDeviceContext()->SetDpi(dpi_, dpi_);
+
+			ThrowIfFailed(
+				CreateWindowSizeDependentResources()
+			);
+		}
+	}
+
+}
+
+#endif // !E2D_USE_DIRECTX10
diff --git a/src/dx/D3D10DeviceResources.h b/src/dx/D3D10DeviceResources.h
new file mode 100644
index 00000000..fcd9fd6f
--- /dev/null
+++ b/src/dx/D3D10DeviceResources.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2016-2018 Easy2D - Nomango
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+
+#ifdef E2D_USE_DIRECTX10
+
+#include "helper.hpp"
+#include "D2DDeviceResources.h"
+#include 
+
+namespace easy2d
+{
+	class E2D_API D3D10DeviceResources
+		: public D2DDeviceResources
+	{
+	public:
+		static HRESULT Create(
+			D3D10DeviceResources** device_resources,
+			HWND hwnd
+		);
+
+		HRESULT HandleDeviceLost();
+
+		void SetLogicalSize(
+			Size logical_size
+		);
+
+		void SetDpi(
+			float dpi
+		);
+
+		void DiscardResources();
+
+		inline ID3D10Device*			GetD3DDevice() const			{ return d3d_device_.Get(); }
+		inline ID3D10RenderTargetView*	GetD3DRenderTargetView() const	{ return d3d_rt_view_.Get(); }
+		inline ID3D10DepthStencilView*	GetD3DDepthStencilView() const	{ return d3d_ds_view_.Get(); }
+		inline IDXGIFactory*			GetDXGIFactory() const			{ return dxgi_factory_.Get(); }
+		inline IDXGISwapChain*			GetDXGISwapChain() const		{ return dxgi_swap_chain_.Get(); }
+
+		inline Size const&				GetLogicalSize() const			{ return logical_size_; }
+		inline Size const&				GetOutputSize() const			{ return output_size_; }
+		inline float					GetDpi() const					{ return dpi_; }
+
+	protected:
+		D3D10DeviceResources();
+
+		virtual ~D3D10DeviceResources();
+
+	protected:
+		HRESULT CreateDeviceResources();
+
+		HRESULT CreateWindowSizeDependentResources();
+
+	private:
+		HWND	hwnd_;
+		float	dpi_;
+		Size	logical_size_;
+		Size	output_size_;
+
+		ComPtr			d3d_device_;
+		ComPtr	d3d_rt_view_;
+		ComPtr	d3d_ds_view_;
+		ComPtr			dxgi_swap_chain_;
+		ComPtr			dxgi_factory_;
+	};
+
+}
+
+#endif // !E2D_USE_DIRECTX10
diff --git a/src/dx/D3D11DeviceResources.cpp b/src/dx/D3D11DeviceResources.cpp
index eff5f86b..9c652c34 100644
--- a/src/dx/D3D11DeviceResources.cpp
+++ b/src/dx/D3D11DeviceResources.cpp
@@ -18,11 +18,15 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#include "DeviceResources.h"
+#include "D3D11DeviceResources.h"
+
+#ifndef E2D_USE_DIRECTX10
+
 #include "../core/Image.h"
-#include "../core/modules.h"
 #include "../core/logs.h"
 
+#pragma comment(lib, "d3d11.lib")
+
 namespace easy2d
 {
 #if defined(_DEBUG)
@@ -30,14 +34,14 @@ namespace easy2d
 	{
 		inline bool SdkLayersAvailable()
 		{
-			HRESULT hr = modules::DirectX::Get().D3D11CreateDevice(
+			HRESULT hr = D3D11CreateDevice(
 				nullptr,
 				D3D_DRIVER_TYPE_NULL,		// There is no need to create a real hardware device.
 				0,
 				D3D11_CREATE_DEVICE_DEBUG,	// Check for the SDK layers.
 				nullptr,					// Any feature level will do.
 				0,
-				D3D11_SDK_VERSION,			// Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
+				D3D11_SDK_VERSION,
 				nullptr,					// No need to keep the D3D device reference.
 				nullptr,					// No need to know the feature level.
 				nullptr						// No need to keep the D3D device context reference.
@@ -109,6 +113,8 @@ namespace easy2d
 	{
 		d3d_device_.Reset();
 		d3d_device_context_.Reset();
+		d3d_rt_view_.Reset();
+		d3d_ds_view_.Reset();
 		dxgi_swap_chain_.Reset();
 		dxgi_factory_.Reset();
 
@@ -119,7 +125,7 @@ namespace easy2d
 	{
 		HRESULT hr = S_OK;
 
-		D3D_FEATURE_LEVEL feature_levels[] =
+		static const D3D_FEATURE_LEVEL feature_levels[] =
 		{
 			D3D_FEATURE_LEVEL_11_1,
 			D3D_FEATURE_LEVEL_11_0,
@@ -144,7 +150,7 @@ namespace easy2d
 		}
 #endif
 
-		hr = modules::DirectX::Get().D3D11CreateDevice(
+		hr = D3D11CreateDevice(
 			nullptr,					// Specify nullptr to use the default adapter.
 			D3D_DRIVER_TYPE_HARDWARE,
 			0,							// Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
@@ -162,7 +168,7 @@ namespace easy2d
 			// If the initialization fails, fall back to the WARP device.
 			// For more information on WARP, see: 
 			// http://go.microsoft.com/fwlink/?LinkId=286690
-			hr = modules::DirectX::Get().D3D11CreateDevice(
+			hr = D3D11CreateDevice(
 				nullptr,
 				D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
 				0,
@@ -218,38 +224,7 @@ namespace easy2d
 			}
 		}
 
-		return hr;
-	}
-
-	HRESULT D3D11DeviceResources::CreateWindowSizeDependentResources()
-	{
-		HRESULT hr = S_OK;
-
-		// Clear the previous window size specific context.
-		ID3D11RenderTargetView* null_views[] = { nullptr };
-		SetTargetBitmap(nullptr);
-		d3d_device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
-		d3d_device_context_->Flush();
-
-		// Calculate the necessary render target size in pixels.
-		output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
-		output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
-
-		// Prevent zero size DirectX content from being created.
-		output_size_.x = std::max(output_size_.x, 1.f);
-		output_size_.y = std::max(output_size_.y, 1.f);
-
-		if (dxgi_swap_chain_)
-		{
-			// If the swap chain already exists, resize it.
-			hr = dxgi_swap_chain_->ResizeBuffers(
-				2, // Double-buffered swap chain.
-				::lround(output_size_.x),
-				::lround(output_size_.y),
-				DXGI_FORMAT_B8G8R8A8_UNORM,
-				0);
-		}
-		else
+		if (SUCCEEDED(hr))
 		{
 			// Setup swap chain
 			DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
@@ -295,8 +270,80 @@ namespace easy2d
 			}
 		}
 
+		return hr;
+	}
+
+	HRESULT D3D11DeviceResources::CreateWindowSizeDependentResources()
+	{
+		if (!dxgi_swap_chain_)
+			return E_UNEXPECTED;
+
+		HRESULT hr = S_OK;
+
+		// Clear the previous window size specific context.
+		ID3D11RenderTargetView* null_views[] = { nullptr };
+		SetTargetBitmap(nullptr);
+		d3d_device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
+		d3d_device_context_->Flush();
+
+		// Calculate the necessary render target size in pixels.
+		output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
+		output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
+
+		// Prevent zero size DirectX content from being created.
+		output_size_.x = std::max(output_size_.x, 1.f);
+		output_size_.y = std::max(output_size_.y, 1.f);
+
+		// If the swap chain already exists, resize it.
+		hr = dxgi_swap_chain_->ResizeBuffers(
+			2, // Double-buffered swap chain.
+			::lround(output_size_.x),
+			::lround(output_size_.y),
+			DXGI_FORMAT_B8G8R8A8_UNORM,
+			0);
+
 		if (SUCCEEDED(hr))
 		{
+			// Create the render target view and set it on the device
+			ComPtr dxgi_back_buffer;
+
+			hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
+
+			if (SUCCEEDED(hr))
+			{
+				d3d_rt_view_ = nullptr;
+				hr = d3d_device_->CreateRenderTargetView(dxgi_back_buffer.Get(), nullptr, &d3d_rt_view_);
+			}
+
+			ComPtr depth_stencil;
+			if (SUCCEEDED(hr))
+			{
+				CD3D11_TEXTURE2D_DESC tex_desc(
+					DXGI_FORMAT_D24_UNORM_S8_UINT,
+					static_cast(output_size_.x),
+					static_cast(output_size_.y),
+					1, // This depth stencil view has only one texture.
+					1, // Use a single mipmap level.
+					D3D11_BIND_DEPTH_STENCIL
+				);
+
+				hr = d3d_device_->CreateTexture2D(&tex_desc, nullptr, &depth_stencil);
+			}
+
+			if (SUCCEEDED(hr))
+			{
+				CD3D11_DEPTH_STENCIL_VIEW_DESC desc(D3D11_DSV_DIMENSION_TEXTURE2D);
+
+				d3d_ds_view_.Reset();
+				hr = d3d_device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &d3d_ds_view_);
+			}
+		}
+
+		if (SUCCEEDED(hr))
+		{
+			ID3D11RenderTargetView* views[] = { d3d_rt_view_.Get() };
+			d3d_device_context_->OMSetRenderTargets(1, views, d3d_ds_view_.Get());
+
 			// Set the 3D rendering viewport to target the entire window.
 			CD3D11_VIEWPORT screen_viewport(
 				0.0f,
@@ -311,13 +358,6 @@ namespace easy2d
 		// swap chain back buffer and set it as the current target.
 		if (SUCCEEDED(hr))
 		{
-			D2D1_BITMAP_PROPERTIES1 bitmap_props =
-				D2D1::BitmapProperties1(
-					D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
-					D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
-					dpi_,
-					dpi_);
-
 			ComPtr dxgi_back_buffer;
 			hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
 
@@ -326,7 +366,11 @@ namespace easy2d
 			{
 				hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface(
 					dxgi_back_buffer.Get(),
-					&bitmap_props,
+					D2D1::BitmapProperties1(
+						D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
+						D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
+						dpi_,
+						dpi_),
 					&target);
 			}
 
@@ -385,3 +429,5 @@ namespace easy2d
 	}
 
 }
+
+#endif // !E2D_USE_DIRECTX10
diff --git a/src/dx/D3D11DeviceResources.h b/src/dx/D3D11DeviceResources.h
index 329b575c..8782966a 100644
--- a/src/dx/D3D11DeviceResources.h
+++ b/src/dx/D3D11DeviceResources.h
@@ -19,6 +19,9 @@
 // THE SOFTWARE.
 
 #pragma once
+
+#ifndef E2D_USE_DIRECTX10
+
 #include "helper.hpp"
 #include "D2DDeviceResources.h"
 #include 
@@ -48,6 +51,8 @@ namespace easy2d
 
 		inline ID3D11Device*			GetD3DDevice() const			{ return d3d_device_.Get(); }
 		inline ID3D11DeviceContext*		GetD3DDeviceContext() const		{ return d3d_device_context_.Get(); }
+		inline ID3D11RenderTargetView*	GetD3DRenderTargetView() const	{ return d3d_rt_view_.Get(); }
+		inline ID3D11DepthStencilView*	GetD3DDepthStencilView() const	{ return d3d_ds_view_.Get(); }
 		inline IDXGIFactory*			GetDXGIFactory() const			{ return dxgi_factory_.Get(); }
 		inline IDXGISwapChain*			GetDXGISwapChain() const		{ return dxgi_swap_chain_.Get(); }
 
@@ -67,16 +72,21 @@ namespace easy2d
 		HRESULT CreateWindowSizeDependentResources();
 
 	private:
-		HWND hwnd_;
-		float dpi_;
-		Size logical_size_;
-		Size output_size_;
+		HWND	hwnd_;
+		float	dpi_;
+		Size	logical_size_;
+		Size	output_size_;
+
 		D3D_FEATURE_LEVEL d3d_feature_level_;
 
-		ComPtr		d3d_device_;
-		ComPtr	d3d_device_context_;
-		ComPtr		dxgi_swap_chain_;
-		ComPtr		dxgi_factory_;
+		ComPtr			d3d_device_;
+		ComPtr		d3d_device_context_;
+		ComPtr	d3d_rt_view_;
+		ComPtr	d3d_ds_view_;
+		ComPtr			dxgi_swap_chain_;
+		ComPtr			dxgi_factory_;
 	};
 
 }
+
+#endif // !E2D_USE_DIRECTX10
diff --git a/src/dx/DeviceResources.h b/src/dx/DeviceResources.h
index fc502d68..f5fb34d3 100644
--- a/src/dx/DeviceResources.h
+++ b/src/dx/DeviceResources.h
@@ -19,9 +19,21 @@
 // THE SOFTWARE.
 
 #pragma once
-#include "D3D11DeviceResources.h"
+#include "../core/macros.h"
+
+#ifdef E2D_USE_DIRECTX10
+#	include "D3D10DeviceResources.h"
+#else
+#	include "D3D11DeviceResources.h"
+#endif
 
 namespace easy2d
 {
+
+#ifdef E2D_USE_DIRECTX10
+	using DeviceResources = D3D10DeviceResources;
+#else
 	using DeviceResources = D3D11DeviceResources;
+#endif
+	
 }
diff --git a/src/math/Matrix.hpp b/src/math/Matrix.hpp
index 851487c3..e56be3ff 100644
--- a/src/math/Matrix.hpp
+++ b/src/math/Matrix.hpp
@@ -57,7 +57,7 @@ namespace easy2d
 			{
 			}
 
-			Matrix(const float* p)
+			explicit Matrix(const float* p)
 			{
 				for (int i = 0; i < 6; i++)
 					m[i] = p[i];