Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Önemli
Bu makale, Windows Uygulama SDK'sı/WinUI için UWP belgelerinden uyarlanmıştır. Bu makaledeki bazı kod örnekleri hala WinUI/Windows Uygulama SDK'sında CoreWindow , CoreApplicationViewve CoreDispatchergibi UWP'ye özgü API'lere başvurur. WinUI eşdeğerleri şunlardır:
-
CoreWindow→ AppWindow veya WinUI Pencere sınıfını kullanma - →
CoreDispatcherDispatcherQueue kullanın -
CoreApplicationViewPencere veya Uygulama Penceresi kullanın
Birleşim birlikte çalışma arabirimleri (ICompositorInterop, ICompositionDrawingSurfaceInterop vb.), Microsoft.UI.Composition nesneleri ile aynı şekilde çalışır.
Microsoft.UI.Composition API'sinde ICompositorInterop, ICompositionDrawingSurfaceInterop ve ICompositionGraphicsDeviceInterop yerel birlikte çalışma arabirimleri sağlanır ve içerik doğrudan oluşturucuya taşınır.
Yerel birlikte çalışma, DirectX dokuları tarafından yedeklenen yüzey nesnelerinin çevresinde yapılandırılmıştır. Yüzeyler CompositionGraphicsDevice adlı bir fabrika nesnesinden oluşturulur. Bu nesne, arka plandaki bir Direct2D veya Direct3D cihaz nesnesi tarafından desteklenir ve bu nesneyi kullanarak yüzeyler için video belleği ayırır. Oluşturma API'si temel alınan DirectX cihazını hiç oluşturmaz. Bir tane oluşturmak ve CompositionGraphicsDevice nesnesine geçirmek uygulamanın sorumluluğundadır. Bir uygulama aynı anda birden fazla CompositionGraphicsDevice nesnesi oluşturabilir ve birden çok CompositionGraphicsDevice nesnesi için işleme cihazıyla aynı DirectX cihazını kullanabilir.
Yüzey oluşturma
Her CompositionGraphicsDevice bir yüzey fabrikası görevi görür. Her yüzey başlangıç boyutuyla (0,0 olabilir) oluşturulur ancak geçerli piksel yoktur. İlk durumundaki bir yüzey, bir görsel ağaçta, örneğin CompositionSurfaceBrush ve SpriteVisual aracılığıyla hemen tüketilebilir, ancak ilk durumunda yüzeyin ekran çıkışı üzerinde hiçbir etkisi yoktur. Belirtilen alfa modu "opak" olsa bile, tüm amaçlar için tamamen saydamdır.
Bazen DirectX cihazları kullanılamaz hale getirilebilir. Bu durum, uygulamanın belirli DirectX API'lerine geçersiz bağımsız değişkenler geçirmesi veya grafik bağdaştırıcısının sistem tarafından sıfırlanması veya sürücünün güncelleştirilmesi gibi diğer nedenlerden biri olabilir. Direct3D, bir uygulamanın cihaz herhangi bir nedenle kaybolursa zaman uyumsuz olarak bulmak için kullanabileceği bir API'ye sahiptir. Bir DirectX cihazı kaybolduğunda uygulamanın cihazı atması, yeni bir cihaz oluşturması ve daha önce hatalı DirectX cihazıyla ilişkilendirilmiş olan CompositionGraphicsDevice nesnelerine geçirmesi gerekir.
Pikselleri bir yüzeye yükleme
Yüzeye piksel yüklemek için uygulamanın, uygulamanın isteklerine bağlı olarak dokuyu veya Direct2D bağlamını temsil eden bir DirectX arabirimi döndüren BeginDraw yöntemini çağırması gerekir. Uygulamanın daha sonra pikselleri bu dokuya işlemesi veya yüklemesi gerekir. Uygulama tamamlandığında EndDraw yöntemini çağırması gerekir. Yalnızca bu noktada, yeni pikseller kompozisyon için mevcut olur, ancak bunlar yine de ekranda görünmez, ta ki görsel ağacın tüm değişiklikleri bir sonraki kez işlenip uygulanan kadar. Görsel ağaç EndDraw çağrılmadan önce işlenirse, devam eden güncelleştirme ekranda görünmez ve yüzey BeginDraw'den önce sahip olduğu içeriği görüntülemeye devam eder. EndDraw çağrıldığında BeginDraw tarafından döndürülen doku veya Direct2D bağlam işaretçisi geçersiz kılınmış olur. Bir uygulama hiçbir zaman bu işaretçiyi EndDraw çağrısının ötesinde önbelleğe almamalıdır.
Uygulama, belirli bir CompositionGraphicsDevice için aynı anda yalnızca bir yüzeyde BeginDraw'ı çağırabilir. BeginDraw çağrıldıktan sonra uygulamanın BeginDraw'ı başka bir yüzeyde çağırmadan önce bu yüzeyde EndDraw çağrısı yapması gerekir. API çevik olduğundan, uygulama birden çok çalışan iş parçacığından işleme gerçekleştirmek istiyorsa bu çağrıları eşitlemekten sorumludur. Bir uygulama bir yüzeyin işlenmesini kesmek ve geçici olarak başka bir yüzeye geçmek istiyorsa SuspendDraw yöntemini kullanabilir. Bu, başka bir BeginDraw işleminin başarılı olmasını sağlar, ancak ilk yüzey güncellemesini ekran kompozisyonu için kullanılabilir yapmaz. Bu, uygulamanın işlemsel bir şekilde birden çok güncelleştirme gerçekleştirmesine olanak tanır. Bir yüzey askıya alındıktan sonra uygulama ResumeDraw yöntemini çağırarak güncelleştirmeye devam edebilir veya EndDraw çağrısı yaparak güncelleştirmenin yapıldığını bildirebilir. Bu, herhangi bir CompositionGraphicsDevice için aynı anda yalnızca bir yüzeyin etkin olarak güncelleştirilebileceği anlamına gelir. Her grafik cihazı bu durumu diğerlerinden bağımsız olarak tutar, bu nedenle bir uygulama farklı grafik cihazlarına aitse aynı anda iki yüzeye işlenebilir. Ancak bu, bu iki yüzey için video belleğinin birlikte havuza alınmasını engeller ve bu nedenle daha az bellek verimlidir.
BeginDraw, SuspendDraw, ResumeDraw ve EndDraw yöntemleri, uygulama yanlış bir işlem gerçekleştirirse (geçersiz bağımsız değişkenleri geçirme veya başka bir uygulamada EndDraw çağırmadan önce bir yüzeyde BeginDraw'ı çağırma gibi) hata döndürür. Bu tür hatalar uygulama hatalarını temsil eder ve bu nedenle beklenti, bunların "fail fast" (hızlı hata tespiti) yöntemiyle ele alınmasıdır. DirectX cihazı kaybolursa BeginDraw hata döndürebilir. Uygulama DirectX cihazını yeniden oluşturup yeniden deneyebileceği için bu hata önemli değildir. Bu nedenle uygulamanın yalnızca işlemeyi atlayarak cihaz kaybını işlemesi beklenir. BeginDraw herhangi bir nedenle başarısız olursa, başlangıç ilk etapta hiçbir zaman başarılı olmadığından uygulamanın EndDraw'u çağırmaması gerekir.
Kaydırma
Performans nedeniyle, bir uygulama BeginDraw'ı çağırdığında, döndürülen doku içeriğinin yüzeyin önceki içeriği olduğu garanti edilmez. Uygulama, içeriğin rastgele olduğunu varsaymalıdır ve bu nedenle uygulama, işlemeden önce yüzeyi temizleyerek veya güncelleştirilmiş dikdörtgenin tamamını kaplayacak kadar opak içerik çizerek tüm piksellere dokunulduğundan emin olmalıdır. Bu, doku işaretçisinin yalnızca BeginDraw ve EndDraw çağrıları arasında geçerli olmasıyla birlikte, uygulamanın önceki içerikleri yüzeyden kopyalamasını imkansız hale getirir. Bu nedenle, uygulamanın aynı yüzey piksel kopyasını gerçekleştirmesini sağlayan bir Scroll yöntemi sunuyoruz.
C++/WinRT kullanım örneği
Aşağıdaki kod örneği, Windows App SDK bağlamında kompozisyon birlikte çalışabilirliği için bir senaryoyu göstermektedir. Örnek, Microsoft.UI.Composition'ın Windows Çalışma Zamanı tabanlı yüzey alanındaki türleri birlikte çalışma üst bilgilerindeki türlerle ve COM tabanlı DirectWrite ve Direct2D API'lerini kullanarak metin işleyen kodla birleştirir. Bu örnekte BeginDraw ve EndDraw kullanarak bu teknolojiler arasında birlikte çalışmayı sorunsuz hale getirmektedir. Örnek, metni düzenlemek için DirectWrite'i ve ardından işlemek için Direct2D'yi kullanır. Oluşturma grafik cihazı, Direct2D cihazını başlatma sırasında doğrudan kabul eder. Bu, BeginDraw'unbir ID2D1DeviceContext arabirim işaretçisi döndürmesine olanak tanır. Bu, uygulamanın döndürülen bir ID3D11Texture2D arabirimini her çizim işleminde sarmalayan bir Direct2D bağlamı oluşturmasından çok daha verimlidir.
Aşağıdaki C++/WinRT kod örneğini denemek için önce Visual Studio'da yeni bir WinUI uygulama projesi oluşturun (gereksinimler için bkz. C++/WinRT için Visual Studio desteği). ve pch.h kaynak kod dosyalarınızın App.cpp içeriğini aşağıdaki kod listeleriyle değiştirin, sonra derleyin ve çalıştırın. Uygulama, "Hello, World!" dizesini saydam bir arka plan üzerinde siyah metin olarak işler.
// NOTE: This example uses UWP-specific APIs. For WinUI, replace CoreWindow with your app's Window handle.
// pch.h
#pragma once
#include <windows.h>
#include <D2d1_1.h>
#include <D3d11_4.h>
#include <Dwrite.h>
#include <Windows.Graphics.DirectX.Direct3D11.interop.h>
#include <Windows.ui.composition.interop.h>
#include <unknwn.h>
#include <winrt/Windows.ApplicationModel.Core.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.DirectX.h>
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Windows.UI.Core.h>
#include <winrt/Windows.UI.Input.h>
// NOTE: This example uses UWP-specific APIs. For WinUI, replace CoreWindow with your app's Window handle.
// App.cpp
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// 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 "pch.h"
using namespace winrt;
using namespace winrt::Windows::ApplicationModel::Core;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Numerics;
using namespace winrt::Windows::Graphics::DirectX;
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
using namespace winrt::Windows::UI;
using namespace winrt::Microsoft::UI::Composition;
using namespace winrt::Windows::UI::Core;
namespace abi
{
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Graphics::DirectX;
using namespace ABI::Microsoft::UI::Composition;
}
// An app-provided helper to render lines of text.
struct SampleText
{
SampleText(winrt::com_ptr<::IDWriteTextLayout> const& text, CompositionGraphicsDevice const& compositionGraphicsDevice) :
m_text(text),
m_compositionGraphicsDevice(compositionGraphicsDevice)
{
// Create the surface just big enough to hold the formatted text block.
DWRITE_TEXT_METRICS metrics;
winrt::check_hresult(m_text->GetMetrics(&metrics));
winrt::Windows::Foundation::Size surfaceSize{ metrics.width, metrics.height };
CompositionDrawingSurface drawingSurface{ m_compositionGraphicsDevice.CreateDrawingSurface(
surfaceSize,
DirectXPixelFormat::B8G8R8A8UIntNormalized,
DirectXAlphaMode::Premultiplied) };
// Cache the interop pointer, since that's what we always use.
m_drawingSurfaceInterop = drawingSurface.as<abi::ICompositionDrawingSurfaceInterop>();
// Draw the text
DrawText();
// If the rendering device is lost, the application will recreate and replace it. We then
// own redrawing our pixels.
m_deviceReplacedEventToken = m_compositionGraphicsDevice.RenderingDeviceReplaced(
[this](CompositionGraphicsDevice const&, RenderingDeviceReplacedEventArgs const&)
{
// Draw the text again.
DrawText();
return S_OK;
});
}
~SampleText()
{
m_compositionGraphicsDevice.RenderingDeviceReplaced(m_deviceReplacedEventToken);
}
// Return the underlying surface to the caller.
auto Surface()
{
// To the caller, the fact that we have a drawing surface is an implementation detail.
// Return the base interface instead.
return m_drawingSurfaceInterop.as<ICompositionSurface>();
}
private:
// The text to draw.
winrt::com_ptr<::IDWriteTextLayout> m_text;
// The composition surface that we use in the visual tree.
winrt::com_ptr<abi::ICompositionDrawingSurfaceInterop> m_drawingSurfaceInterop;
// The device that owns the surface.
CompositionGraphicsDevice m_compositionGraphicsDevice{ nullptr };
//winrt::com_ptr<abi::ICompositionGraphicsDevice> m_compositionGraphicsDevice2;
// For managing our event notifier.
winrt::event_token m_deviceReplacedEventToken;
// We may detect device loss on BeginDraw calls. This helper handles this condition or other
// errors.
bool CheckForDeviceRemoved(HRESULT hr)
{
if (hr == S_OK)
{
// Everything is fine: go ahead and draw.
return true;
}
if (hr == DXGI_ERROR_DEVICE_REMOVED)
{
// We can't draw at this time, but this failure is recoverable. Just skip drawing for
// now. We will be asked to draw again once the Direct3D device is recreated.
return false;
}
// Any other error is unexpected and, therefore, fatal.
winrt::check_hresult(hr);
return true;
}
// Renders the text into our composition surface
void DrawText()
{
// Begin our update of the surface pixels. If this is our first update, we are required
// to specify the entire surface, which nullptr is shorthand for (but, as it works out,
// any time we make an update we touch the entire surface, so we always pass nullptr).
winrt::com_ptr<::ID2D1DeviceContext> d2dDeviceContext;
POINT offset;
if (CheckForDeviceRemoved(m_drawingSurfaceInterop->BeginDraw(nullptr,
__uuidof(ID2D1DeviceContext), d2dDeviceContext.put_void(), &offset)))
{
d2dDeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.f));
// Create a solid color brush for the text. A more sophisticated application might want
// to cache and reuse a brush across all text elements instead, taking care to recreate
// it in the event of device removed.
winrt::com_ptr<::ID2D1SolidColorBrush> brush;
winrt::check_hresult(d2dDeviceContext->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black, 1.0f), brush.put()));
// Draw the line of text at the specified offset, which corresponds to the top-left
// corner of our drawing surface. Notice we don't call BeginDraw on the D2D device
// context; this has already been done for us by the composition API.
d2dDeviceContext->DrawTextLayout(D2D1::Point2F((float)offset.x, (float)offset.y), m_text.get(),
brush.get());
// Our update is done. EndDraw never indicates rendering device removed, so any
// failure here is unexpected and, therefore, fatal.
winrt::check_hresult(m_drawingSurfaceInterop->EndDraw());
}
}
};
struct DeviceLostEventArgs
{
DeviceLostEventArgs(IDirect3DDevice const& device) : m_device(device) {}
IDirect3DDevice Device() { return m_device; }
static DeviceLostEventArgs Create(IDirect3DDevice const& device) { return DeviceLostEventArgs{ device }; }
private:
IDirect3DDevice m_device;
};
struct DeviceLostHelper
{
DeviceLostHelper() = default;
~DeviceLostHelper()
{
StopWatchingCurrentDevice();
m_onDeviceLostHandler = nullptr;
}
IDirect3DDevice CurrentlyWatchedDevice() { return m_device; }
void WatchDevice(winrt::com_ptr<::IDXGIDevice> const& dxgiDevice)
{
// If we're currently listening to a device, then stop.
StopWatchingCurrentDevice();
// Set the current device to the new device.
m_device = nullptr;
winrt::check_hresult(::CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<::IInspectable**>(winrt::put_abi(m_device))));
// Get the DXGI Device.
m_dxgiDevice = dxgiDevice;
// QI For the ID3D11Device4 interface.
winrt::com_ptr<::ID3D11Device4> d3dDevice{ m_dxgiDevice.as<::ID3D11Device4>() };
// Create a wait struct.
m_onDeviceLostHandler = nullptr;
m_onDeviceLostHandler = ::CreateThreadpoolWait(DeviceLostHelper::OnDeviceLost, (PVOID)this, nullptr);
// Create a handle and a cookie.
m_eventHandle.attach(::CreateEvent(nullptr, false, false, nullptr));
winrt::check_bool(bool{ m_eventHandle });
m_cookie = 0;
// Register for device lost.
::SetThreadpoolWait(m_onDeviceLostHandler, m_eventHandle.get(), nullptr);
winrt::check_hresult(d3dDevice->RegisterDeviceRemovedEvent(m_eventHandle.get(), &m_cookie));
}
void StopWatchingCurrentDevice()
{
if (m_dxgiDevice)
{
// QI For the ID3D11Device4 interface.
auto d3dDevice{ m_dxgiDevice.as<::ID3D11Device4>() };
// Unregister from the device lost event.
::CloseThreadpoolWait(m_onDeviceLostHandler);
d3dDevice->UnregisterDeviceRemoved(m_cookie);
// Clear member variables.
m_onDeviceLostHandler = nullptr;
m_eventHandle.close();
m_cookie = 0;
m_device = nullptr;
}
}
void DeviceLost(winrt::delegate<DeviceLostHelper const*, DeviceLostEventArgs const&> const& handler)
{
m_deviceLost = handler;
}
winrt::delegate<DeviceLostHelper const*, DeviceLostEventArgs const&> m_deviceLost;
private:
void RaiseDeviceLostEvent(IDirect3DDevice const& oldDevice)
{
m_deviceLost(this, DeviceLostEventArgs::Create(oldDevice));
}
static void CALLBACK OnDeviceLost(PTP_CALLBACK_INSTANCE /* instance */, PVOID context, PTP_WAIT /* wait */, TP_WAIT_RESULT /* waitResult */)
{
auto deviceLostHelper = reinterpret_cast<DeviceLostHelper*>(context);
auto oldDevice = deviceLostHelper->m_device;
deviceLostHelper->StopWatchingCurrentDevice();
deviceLostHelper->RaiseDeviceLostEvent(oldDevice);
}
private:
IDirect3DDevice m_device;
winrt::com_ptr<::IDXGIDevice> m_dxgiDevice;
PTP_WAIT m_onDeviceLostHandler{ nullptr };
winrt::handle m_eventHandle;
DWORD m_cookie{ 0 };
};
struct SampleApp : implements<SampleApp, IFrameworkViewSource, IFrameworkView>
{
IFrameworkView CreateView()
{
return *this;
}
void Initialize(CoreApplicationView const&)
{
}
// Run once when the application starts up
void Initialize()
{
// Create a Direct2D device.
CreateDirect2DDevice();
// To create a composition graphics device, we need to QI for another interface
winrt::com_ptr<abi::ICompositorInterop> compositorInterop{ m_compositor.as<abi::ICompositorInterop>() };
// Create a graphics device backed by our D3D device
winrt::com_ptr<abi::ICompositionGraphicsDevice> compositionGraphicsDeviceIface;
winrt::check_hresult(compositorInterop->CreateGraphicsDevice(
m_d2dDevice.get(),
compositionGraphicsDeviceIface.put()));
m_compositionGraphicsDevice = compositionGraphicsDeviceIface.as<CompositionGraphicsDevice>();
}
void Load(hstring const&)
{
}
void Uninitialize()
{
}
void Run()
{
CoreWindow window = CoreWindow::GetForCurrentThread();
window.Activate();
CoreDispatcher dispatcher = window.Dispatcher();
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
void SetWindow(CoreWindow const& window)
{
m_compositor = Compositor{};
m_target = m_compositor.CreateTargetForCurrentView();
ContainerVisual root = m_compositor.CreateContainerVisual();
m_target.Root(root);
Initialize();
winrt::check_hresult(
::DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(m_dWriteFactory),
reinterpret_cast<::IUnknown**>(m_dWriteFactory.put())
)
);
winrt::check_hresult(
m_dWriteFactory->CreateTextFormat(
L"Segoe UI",
nullptr,
DWRITE_FONT_WEIGHT_REGULAR,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
36.f,
L"en-US",
m_textFormat.put()
)
);
Rect windowBounds{ window.Bounds() };
std::wstring text{ L"Hello, World!" };
winrt::check_hresult(
m_dWriteFactory->CreateTextLayout(
text.c_str(),
(uint32_t)text.size(),
m_textFormat.get(),
windowBounds.Width,
windowBounds.Height,
m_textLayout.put()
)
);
Visual textVisual{ CreateVisualFromTextLayout(m_textLayout) };
textVisual.Size({ windowBounds.Width, windowBounds.Height });
root.Children().InsertAtTop(textVisual);
}
// Called when Direct3D signals the device lost event.
void OnDirect3DDeviceLost(DeviceLostHelper const* /* sender */, DeviceLostEventArgs const& /* args */)
{
// Create a new Direct2D device.
CreateDirect2DDevice();
// Restore our composition graphics device to good health.
winrt::com_ptr<abi::ICompositionGraphicsDeviceInterop> compositionGraphicsDeviceInterop{ m_compositionGraphicsDevice.as<abi::ICompositionGraphicsDeviceInterop>() };
winrt::check_hresult(compositionGraphicsDeviceInterop->SetRenderingDevice(m_d2dDevice.get()));
}
// Create a surface that is asynchronously filled with an image
ICompositionSurface CreateSurfaceFromTextLayout(winrt::com_ptr<::IDWriteTextLayout> const& text)
{
// Create our wrapper object that will handle downloading and decoding the image (assume
// throwing new here).
SampleText textSurface{ text, m_compositionGraphicsDevice };
// The caller is only interested in the underlying surface.
return textSurface.Surface();
}
// Create a visual that holds an image.
Visual CreateVisualFromTextLayout(winrt::com_ptr<::IDWriteTextLayout> const& text)
{
// Create a sprite visual
SpriteVisual spriteVisual{ m_compositor.CreateSpriteVisual() };
// The sprite visual needs a brush to hold the image.
CompositionSurfaceBrush surfaceBrush{
m_compositor.CreateSurfaceBrush(CreateSurfaceFromTextLayout(text))
};
// Associate the brush with the visual.
CompositionBrush brush{ surfaceBrush.as<CompositionBrush>() };
spriteVisual.Brush(brush);
// Return the visual to the caller as an IVisual.
return spriteVisual;
}
private:
CompositionTarget m_target{ nullptr };
Compositor m_compositor{ nullptr };
winrt::com_ptr<::ID2D1Device> m_d2dDevice;
winrt::com_ptr<::IDXGIDevice> m_dxgiDevice;
//winrt::com_ptr<abi::ICompositionGraphicsDevice> m_compositionGraphicsDevice;
CompositionGraphicsDevice m_compositionGraphicsDevice{ nullptr };
std::vector<SampleText> m_textSurfaces;
DeviceLostHelper m_deviceLostHelper;
winrt::com_ptr<::IDWriteFactory> m_dWriteFactory;
winrt::com_ptr<::IDWriteTextFormat> m_textFormat;
winrt::com_ptr<::IDWriteTextLayout> m_textLayout;
// This helper creates a Direct2D device, and registers for a device loss
// notification on the underlying Direct3D device. When that notification is
// raised, the OnDirect3DDeviceLost method is called.
void CreateDirect2DDevice()
{
uint32_t createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
// Array with DirectX hardware feature levels in order of preference.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
// Create the Direct3D 11 API device object and a corresponding context.
winrt::com_ptr<::ID3D11Device> d3DDevice;
winrt::com_ptr<::ID3D11DeviceContext> d3DImmediateContext;
D3D_FEATURE_LEVEL d3dFeatureLevel{ D3D_FEATURE_LEVEL_9_1 };
winrt::check_hresult(
::D3D11CreateDevice(
nullptr, // Default adapter.
D3D_DRIVER_TYPE_HARDWARE,
0, // Not asking for a software driver, so not passing a module to one.
createDeviceFlags, // Set debug and Direct2D compatibility flags.
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
d3DDevice.put(),
&d3dFeatureLevel,
d3DImmediateContext.put()
)
);
// Initialize Direct2D resources.
D2D1_FACTORY_OPTIONS d2d1FactoryOptions{ D2D1_DEBUG_LEVEL_NONE };
// Initialize the Direct2D Factory.
winrt::com_ptr<::ID2D1Factory1> d2D1Factory;
winrt::check_hresult(
::D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(d2D1Factory),
&d2d1FactoryOptions,
d2D1Factory.put_void()
)
);
// Create the Direct2D device object.
// Obtain the underlying DXGI device of the Direct3D device.
m_dxgiDevice = d3DDevice.as<::IDXGIDevice>();
m_d2dDevice = nullptr;
winrt::check_hresult(
d2D1Factory->CreateDevice(m_dxgiDevice.get(), m_d2dDevice.put())
);
m_deviceLostHelper.WatchDevice(m_dxgiDevice);
m_deviceLostHelper.DeviceLost({ this, &SampleApp::OnDirect3DDeviceLost });
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
CoreApplication::Run(winrt::make<SampleApp>());
}
Windows developer