Bagikan melalui


Mulai cepat Direct2D untuk Windows 8

Direct2D adalah API kode asli dan mode langsung untuk membuat grafik 2D. Topik ini menggambarkan cara menggunakan Direct2D untuk menggambar ke Windows::UI::Core::CoreWindow.

Topik ini berisi bagian berikut:

Menggambar Persegi Panjang Sederhana

Untuk menggambar persegi menggunakan GDI, Anda dapat menangani pesan WM_PAINT , seperti yang diperlihatkan dalam kode berikut.

switch(message)
{

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);

            // Obtain the size of the drawing area.
            RECT rc;
            GetClientRect(
                hwnd,
                &rc
            );          

            // Save the original object
            HGDIOBJ original = NULL;
            original = SelectObject(
                ps.hdc,
                GetStockObject(DC_PEN)
            );

            // Create a pen.            
            HPEN blackPen = CreatePen(PS_SOLID, 3, 0);

            // Select the pen.
            SelectObject(ps.hdc, blackPen);

            // Draw a rectangle.
            Rectangle(
                ps.hdc, 
                rc.left + 100, 
                rc.top + 100, 
                rc.right - 100, 
                rc.bottom - 100);   

            DeleteObject(blackPen);

            // Restore the original object
            SelectObject(ps.hdc, original);

            EndPaint(hwnd, &ps);
        }
        return 0;

// Code for handling other messages. 

Kode untuk menggambar persegi panjang yang sama dengan Direct2D serupa: ia membuat sumber daya gambar, menggambarkan bentuk untuk menggambar, menggambar bentuk, lalu melepaskan sumber daya gambar. Bagian berikut menjelaskan masing-masing langkah ini secara rinci.

Langkah 1: Sertakan Header Direct2D

Selain header yang diperlukan untuk aplikasi, sertakan header d2d1.h dan d2d1_1.h.

Langkah 2: Membuat ID2D1Factory1

Salah satu hal pertama yang dilakukan contoh Direct2D adalah membuat ID2D1Factory1.

DX::ThrowIfFailed(
        D2D1CreateFactory(
            D2D1_FACTORY_TYPE_SINGLE_THREADED,
            __uuidof(ID2D1Factory1),
            &options,
            &m_d2dFactory
            )
        );

Antarmuka ID2D1Factory1 adalah titik awal untuk menggunakan Direct2D; gunakan ID2D1Factory1 untuk membuat sumber daya Direct2D.

Saat membuat pabrik, Anda dapat menentukan apakah itu multi-atau berutas tunggal. (Untuk informasi selengkapnya tentang pabrik multi-utas, lihat keterangan di halaman referensi ID2D1Factory.) Contoh ini membuat pabrik berutas tunggal.

Secara umum, aplikasi Anda harus membuat pabrik sekali dan mempertahankannya selama masa pakai aplikasi.

Langkah 3: Membuat ID2D1Device dan ID2D1DeviceContext

Setelah Anda membuat pabrik, gunakan untuk membuat perangkat Direct2D lalu gunakan perangkat untuk membuat konteks perangkat Direct2D. Untuk membuat objek Direct2D ini, Anda harus memiliki perangkat Direct3D 11 , perangkat DXGI, dan rantai pertukaran DXGI. Lihat Konteks Perangkat dan Perangkat untuk informasi tentang membuat prasyarat yang diperlukan.


    // Obtain the underlying DXGI device of the Direct3D11.1 device.
    DX::ThrowIfFailed(
        m_d3dDevice.As(&dxgiDevice)
        );

    // Obtain the Direct2D device for 2-D rendering.
    DX::ThrowIfFailed(
        m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
        );

    // And get its corresponding device context object.
    DX::ThrowIfFailed(
        m_d2dDevice->CreateDeviceContext(
            D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
            &m_d2dContext
            )
        );

Konteks perangkat adalah perangkat yang dapat melakukan operasi menggambar dan membuat sumber daya gambar yang bergantung pada perangkat seperti kuas. Anda juga menggunakan konteks perangkat untuk menautkan ID2D1Bitmap ke permukaan DXGI untuk digunakan sebagai target render. Konteks perangkat dapat dirender ke berbagai jenis target.

Kode di sini mendeklarasikan properti untuk bitmap yang terhubung ke rantai pertukaran DXGI yang dirender ke CoreWindow. Metode ID2D1DeviceContext::CreateBitmapFromDxgiSurface mendapatkan permukaan Direct2D dari permukaan DXGI. Ini membuatnya jadi apa pun yang dirender ke target ID2D1Bitmap dirender ke permukaan rantai pertukaran.

Setelah Anda memiliki permukaan Direct2D, gunakan metode ID2D1DeviceContext::SetTarget untuk mengaturnya sebagai target render aktif.

    // Now we set up the Direct2D render target bitmap linked to the swapchain. 
    // Whenever we render to this bitmap, it will be directly rendered to the 
    // swapchain 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_PREMULTIPLIED),
            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
            )
        );

    // So now we can set the Direct2D render target.
    m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());

Langkah 4: Buat Brush

Seperti pabrik, konteks perangkat dapat membuat sumber daya gambar. Dalam contoh ini, konteks perangkat membuat kuas.

ComPtr<ID2D1SolidColorBrush> pBlackBrush;
DX::ThrowIfFailed(
   m_d2dContext->CreateSolidColorBrush(
        D2D1::ColorF(D2D1::ColorF::Black),
        &pBlackBrush
        )
);

Kuas adalah objek yang melukis area, seperti goresan bentuk atau isian geometri. Kuas dalam contoh ini melukis area dengan warna solid yang telah ditentukan sebelumnya, hitam.

Direct2D juga menyediakan jenis kuas lainnya: kuas gradien untuk melukis gradien linier dan radial, kuas bitmap untuk lukisan dengan bitmap dan pola, dan dimulai pada Windows 8, sikat gambar untuk lukisan dengan gambar yang dirender.

Beberapa API gambar menyediakan pena untuk menggambar kerangka dan kuas untuk mengisi bentuk. Direct2D berbeda: tidak menyediakan objek pena tetapi menggunakan kuas untuk menggambar kerangka dan mengisi bentuk. Saat menggambar kerangka, gunakan antarmuka ID2D1StrokeStyle, atau mulai dari Windows 8 antarmuka ID2D1StrokeStyle1, dengan kuas untuk mengontrol operasi membelai jalur.

Kuas hanya dapat digunakan dengan target render yang membuatnya dan dengan target render lainnya di domain sumber daya yang sama. Secara umum, Anda harus membuat kuas sekali dan mempertahankannya untuk kehidupan target render yang membuatnya. ID2D1SolidColorBrush adalah pengecualian kesepian; karena relatif murah untuk dibuat, Anda dapat membuat ID2D1SolidColorBrush setiap kali Anda menggambar bingkai, tanpa hit performa yang nyata. Anda juga dapat menggunakan ID2D1SolidColorBrush tunggal dan hanya mengubah warna atau tingkat keburamannya setiap kali Anda menggunakannya.

Langkah 5: Gambar Persegi Panjang

Selanjutnya, gunakan konteks perangkat untuk menggambar persegi panjang.

 
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, &parameters);
);

Metode DrawRectangle mengambil dua parameter: persegi panjang yang akan digambar, dan kuas yang akan digunakan untuk mengecat kerangka persegi panjang. Secara opsional, Anda juga dapat menentukan lebar goresan, pola tanda hubung, gabungan garis, dan opsi batas akhir.

Anda harus memanggil metode BeginDraw sebelum mengeluarkan perintah gambar apa pun, dan Anda harus memanggil metode EndDraw setelah Anda selesai mengeluarkan perintah gambar. Metode EndDraw mengembalikan HRESULT yang menunjukkan apakah perintah gambar berhasil. Jika tidak berhasil, fungsi pembantu ThrowIfFailed akan memberikan pengecualian.

Metode IDXGISwapChain::P resent menukar permukaan buffer dengan permukaan pada layar untuk menampilkan hasilnya.

Contoh kode

Kode dalam topik ini menunjukkan elemen dasar aplikasi Direct2D. Untuk keringkasan, topik menghilangkan kerangka kerja aplikasi dan kode penanganan kesalahan yang merupakan karakteristik dari aplikasi yang ditulis dengan baik.