Cara merender dengan menggunakan konteks perangkat Direct2D
Dalam topik ini Anda akan belajar tentang membuat konteks perangkat Direct2D di Windows 8. Informasi ini berlaku untuk Anda jika Anda mengembangkan aplikasi Windows Store atau aplikasi desktop dengan menggunakan Direct2D. Topik ini menjelaskan tujuan objek konteks perangkat Direct2D, cara membuat objek tersebut , dan panduan langkah demi langkah tentang merender dan menampilkan primitif dan gambar Direct2D. Anda juga akan mempelajari tentang beralih target render dan menambahkan efek ke aplikasi Anda.
- Apa itu perangkat Direct2D?
- Apa itu konteks perangkat Direct2D?
- Penyajian dengan Direct2D di Windows 8
- Mengapa menggunakan konteks perangkat untuk merender?
- Cara membuat konteks perangkat Direct2D untuk penyajian
- Memilih target
- Cara merender dan menampilkan
Apa itu perangkat Direct2D?
Anda memerlukan perangkat Direct2D dan perangkat Direct3D untuk membuat konteks perangkat Direct2D. Perangkat Direct2D (mengekspos penunjuk antarmuka ID2D1Device) mewakili adaptor tampilan. Perangkat Direct3D (mengekspos pointer antarmuka ID3D11Device ) dikaitkan dengan perangkat Direct2D. Setiap aplikasi harus memiliki satu perangkat Direct2D, tetapi dapat memiliki lebih dari satu perangkat.
Apa itu konteks perangkat Direct2D?
Konteks perangkat Direct2D (mengekspos penunjuk antarmuka ID2D1DeviceContext) mewakili sekumpulan buffer status dan perintah yang Anda gunakan untuk merender ke target. Anda dapat memanggil metode pada konteks perangkat untuk mengatur status alur dan menghasilkan perintah penyajian dengan menggunakan sumber daya yang dimiliki oleh perangkat.
Penyajian dengan Direct2D di Windows 8
Pada Windows 7 dan yang lebih lama, Anda menggunakan ID2D1HwndRenderTarget atau antarmuka target render lain untuk dirender ke jendela atau permukaan. Dimulai dengan Windows 8, kami tidak menyarankan penyajian dengan menggunakan metode yang mengandalkan antarmuka seperti ID2D1HwndRenderTarget karena tidak akan berfungsi dengan aplikasi Windows Store. Anda dapat menggunakan konteks perangkat untuk merender ke Hwnd jika Anda ingin membuat aplikasi desktop dan masih memanfaatkan fitur tambahan konteks perangkat. Namun, konteks perangkat diperlukan untuk merender konten di aplikasi Windows Store dengan Direct2D.
Mengapa menggunakan konteks perangkat untuk merender?
- Anda dapat merender untuk aplikasi Windows Store.
- Anda dapat mengubah target render kapan saja sebelum, selama, dan setelah penyajian. Konteks perangkat memastikan bahwa panggilan ke metode menggambar dijalankan secara berurutan dan menerapkannya saat Anda mengalihkan target render.
- Anda dapat menggunakan lebih dari satu jenis jendela dengan konteks perangkat. Anda dapat menggunakan konteks perangkat dan rantai pertukaran DXGI untuk merender langsung ke Windows::UI::Core::CoreWindow atau Windows::UI::XAML::SwapChainBackgroundPanel.
- Anda dapat menggunakan konteks perangkat Direct2D untuk membuat efek Direct2D dan merender output efek gambar atau grafik efek ke target render.
- Anda dapat memiliki beberapa konteks perangkat, yang dapat membantu untuk meningkatkan performa di aplikasi berutas. Lihat Aplikasi Direct2D multithreaded untuk informasi selengkapnya.
- Konteks perangkat berinterogasi erat dengan Direct3D, memberi Anda lebih banyak akses ke opsi Direct3D.
Cara membuat konteks perangkat Direct2D untuk penyajian
Kode di sini menunjukkan kepada Anda cara membuat perangkat Direct3D11, mendapatkan perangkat DXGI terkait, membuat perangkat Direct2D, lalu akhirnya membuat konteks perangkat Direct2D untuk penyajian.
Berikut adalah diagram panggilan metode dan antarmuka yang digunakan kode ini.
Catatan
Kode ini mengasumsikan Anda sudah memiliki objek ID2D1Factory1, untuk informasi selengkapnya lihat halaman referensi ID2D1Factory.
// This flag adds support for surfaces with a different color channel ordering than the API default.
// You need it for compatibility with Direct2D.
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
// This array defines the set of DirectX hardware feature levels this app supports.
// The ordering is important and you should preserve it.
// Don't forget to declare your app's minimum required feature level in its
// description. All apps are assumed to support 9.1 unless otherwise stated.
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 DX11 API device object, and get a corresponding context.
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
DX::ThrowIfFailed(
D3D11CreateDevice(
nullptr, // specify null to use the default adapter
D3D_DRIVER_TYPE_HARDWARE,
0,
creationFlags, // optionally set debug and Direct2D compatibility flags
featureLevels, // list of feature levels this app can support
ARRAYSIZE(featureLevels), // number of possible feature levels
D3D11_SDK_VERSION,
&device, // returns the Direct3D device created
&m_featureLevel, // returns feature level of device created
&context // returns the device immediate context
)
);
ComPtr<IDXGIDevice> dxgiDevice;
// Obtain the underlying DXGI device of the Direct3D11 device.
DX::ThrowIfFailed(
device.As(&dxgiDevice)
);
// Obtain the Direct2D device for 2-D rendering.
DX::ThrowIfFailed(
m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
);
// Get Direct2D device's corresponding device context object.
DX::ThrowIfFailed(
m_d2dDevice->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&m_d2dContext
)
);
Mari kita telusuri langkah-langkah dalam sampel kode sebelumnya.
Dapatkan penunjuk antarmuka ID3D11Device, Anda akan memerlukannya untuk membuat konteks perangkat.
Nyatakan bendera pembuatan untuk menyiapkan perangkat Direct3D untuk dukungan BGRA. Direct2D memerlukan urutan warna BGRA.
Deklarasikan array entri D3D_FEATURE_LEVEL yang mewakili serangkaian tingkat fitur yang akan didukung aplikasi Anda.
Catatan
Direct3D mencari daftar Anda hingga menemukan tingkat fitur yang didukung oleh sistem host.
Gunakan fungsi D3D11CreateDevice untuk membuat objek ID3D11Device, fungsi juga akan mengembalikan objek ID3D11DeviceContext, tetapi objek tersebut tidak diperlukan untuk contoh ini.
Kueri perangkat Direct3D 11 untuk antarmuka Perangkat DXGI-nya.
Buat objek ID2D1Device dengan memanggil metode ID2D1Factory::CreateDevice dan meneruskan objek IDXGIDevice.
Buat penunjuk ID2D1DeviceContext menggunakan metode ID2D1Device::CreateDeviceContext.
Memilih target
Kode di sini menunjukkan kepada Anda cara mendapatkan tekstur Direct3D 2 dimensi untuk buffer belakang jendela dan membuat target bitmap yang ditautkan ke tekstur ini yang dirender konteks perangkat Direct2D.
// Allocate a descriptor.
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Width = 0; // use automatic sizing
swapChainDesc.Height = 0;
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1; // don't use multi-sampling
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2; // use double buffering to enable flip
swapChainDesc.Scaling = DXGI_SCALING_NONE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all apps must use this SwapEffect
swapChainDesc.Flags = 0;
// Identify the physical adapter (GPU or card) this device is runs on.
ComPtr<IDXGIAdapter> dxgiAdapter;
DX::ThrowIfFailed(
dxgiDevice->GetAdapter(&dxgiAdapter)
);
// Get the factory object that created the DXGI device.
ComPtr<IDXGIFactory2> dxgiFactory;
DX::ThrowIfFailed(
dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
);
// Get the final swap chain for this window from the DXGI factory.
DX::ThrowIfFailed(
dxgiFactory->CreateSwapChainForCoreWindow(
device.Get(),
reinterpret_cast<IUnknown*>(m_window),
&swapChainDesc,
nullptr, // allow on all displays
&m_swapChain
)
);
// Ensure that DXGI doesn't queue more than one frame at a time.
DX::ThrowIfFailed(
dxgiDevice->SetMaximumFrameLatency(1)
);
// Get the backbuffer for this window which is be the final 3D render target.
ComPtr<ID3D11Texture2D> backBuffer;
DX::ThrowIfFailed(
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
);
// Now we set up the Direct2D render target bitmap linked to the swapchain.
// Whenever we render to this bitmap, it is directly rendered to the
// swap chain associated with the window.
D2D1_BITMAP_PROPERTIES1 bitmapProperties =
BitmapProperties1(
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE),
m_dpi,
m_dpi
);
// Direct2D needs the dxgi version of the backbuffer surface pointer.
ComPtr<IDXGISurface> dxgiBackBuffer;
DX::ThrowIfFailed(
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
);
// Get a D2D surface from the DXGI back buffer to use as the D2D render target.
DX::ThrowIfFailed(
m_d2dContext->CreateBitmapFromDxgiSurface(
dxgiBackBuffer.Get(),
&bitmapProperties,
&m_d2dTargetBitmap
)
);
// Now we can set the Direct2D render target.
m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());
Mari kita telusuri langkah-langkah dalam contoh kode sebelumnya.
Alokasikan struktur DXGI_SWAP_CHAIN_DESC1 dan tentukan pengaturan untuk rantai pertukaran.
Pengaturan ini menunjukkan contoh cara membuat rantai pertukaran yang dapat digunakan aplikasi Windows Store.
Dapatkan adaptor yang dijalankan perangkat Direct3D dan Perangkat DXGI dan dapatkan objek IDXGIFactory yang terkait dengannya. Anda harus menggunakan pabrik DXGI ini untuk memastikan rantai pertukaran dibuat pada adaptor yang sama.
Panggil metode IDXGIFactory2::CreateSwapChainForCoreWindow untuk membuat rantai pertukaran. Gunakan kelas Windows::UI::CoreWindow untuk jendela utama aplikasi Windows Store.
Pastikan untuk mengatur latensi bingkai maksimum ke 1 untuk meminimalkan konsumsi daya.
Jika Anda ingin merender konten Direct2D di aplikasi Windows Store, lihat metode CreateSwapChainForComposition.
Dapatkan buffer belakang dari rantai pertukaran. Buffer belakang mengekspos antarmuka ID3D11Texture2D yang dialokasikan oleh rantai pertukaran
Deklarasikan struktur D2D1_BITMAP_PROPERTIES1 dan atur nilai properti. Atur format piksel ke BGRA karena ini adalah format perangkat Direct3D dan penggunaan Perangkat DXGI.
Dapatkan buffer belakang sebagai IDXGISurface untuk diteruskan ke Direct2D. Direct2D tidak menerima ID3D11Texture2D secara langsung.
Buat objek ID2D1Bitmap dari buffer belakang menggunakan metode ID2D1DeviceContext::CreateBitmapFromDxgiSurface.
Sekarang bitmap Direct2D ditautkan ke buffer belakang. Atur target pada konteks perangkat Direct2D ke bitmap.
Cara merender dan menampilkan
Sekarang setelah Anda memiliki bitmap target, Anda dapat menggambar primitif, gambar, efek gambar, dan teks ke dalamnya menggunakan konteks perangkat Direct2D. Kode di sini menunjukkan kepada Anda cara menggambar persegi panjang.
ComPtr<ID2D1SolidColorBrush> pBlackBrush;
DX::ThrowIfFailed(
m_d2dContext->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black),
&pBlackBrush
)
);
m_d2dContext->BeginDraw();
m_d2dContext->DrawRectangle(
D2D1::RectF(
rc.left + 100.0f,
rc.top + 100.0f,
rc.right - 100.0f,
rc.bottom - 100.0f),
pBlackBrush);
DX::ThrowIfFailed(
m_d2dContext->EndDraw()
);
DX::ThrowIfFailed(
m_swapChain->Present1(1, 0, ¶meters);
);
Mari kita telusuri langkah-langkah dalam contoh kode sebelumnya.
- Panggil CreateSolidColorBrush untuk membuat kuas untuk melukis persegi panjang.
- Panggil metode BeginDraw sebelum mengeluarkan perintah gambar apa pun.
- Panggil metode DrawRectangle persegi panjang yang akan digambar dan kuas.
- Panggil metode EndDraw setelah Anda selesai mengeluarkan perintah menggambar.
- Tampilkan hasilnya dengan memanggil metode IDXGISwapChain::P resent .
Sekarang Anda dapat menggunakan konteks perangkat Direct2D menggambar primitif, gambar, efek gambar, dan teks ke layar.