Memulai (DirectXMath)

Pustaka DirectXMath mengimplementasikan antarmuka yang optimal dan portabel untuk operasi aljabar aritmatika dan linier pada vektor floating-point presisi tunggal (2D, 3D, dan 4D) atau matriks (3×3 dan 4×4). Pustaka memiliki beberapa dukungan terbatas untuk operasi vektor bilangan bulat. Operasi ini digunakan secara ekstensif dalam penyajian dan animasi oleh program grafis. Tidak ada dukungan untuk vektor presisi ganda (termasuk panjang, celana pendek, atau byte), dan hanya operasi vektor bilangan bulat terbatas.

Pustaka tersedia di berbagai platform Windows. Karena pustaka menyediakan fungsionalitas yang tidak tersedia sebelumnya, versi ini menggantikan pustaka berikut:

  • Pustaka Xbox Math yang disediakan oleh header Xboxmath.h
  • Pustaka D3DX 9 yang disediakan oleh D3DX 9 DLL
  • Pustaka matematika D3DX 10 disediakan melalui D3DX 10 DLL
  • Pustaka Matematika XNA yang disediakan oleh header xnamath.h di DirectX SDK dan Xbox 360 XDK

Bagian ini menguraikan dasar-dasar memulai.

Unduh

Pustaka DirectXMath disertakan dalam Windows SDK. Atau Anda dapat mengunduhnya dari GitHub/Microsoft/DirectXMath. Situs ini juga berisi proyek sampel terkait.

Persyaratan Sistem Run-Time

Pustaka DirectXMath menggunakan instruksi prosesor khusus untuk operasi vektor saat tersedia. Untuk menghindari program menghasilkan kesalahan "pengecualian instruksi yang tidak diketahui", periksa dukungan prosesor dengan memanggil XMVerifyCPUSupport sebelum menggunakan Pustaka DirectXMath.

Ini adalah persyaratan dukungan run-time Pustaka DirectXMath dasar:

  • Kompilasi default pada platform Windows (x86/x64) memerlukan dukungan instruksi SSE/SSE2.
  • Kompliasi default pada platform Windows RT memerlukan dukungan instruksi ARM-NEON.
  • Kompilasi dengan _XM_NO_INTRINSICS_ yang ditentukan hanya memerlukan dukungan operasi floating-point standar.

Catatan

Saat Anda memanggil XMVerifyCPUSupport, sertakan <windows.h> sebelum Anda menyertakan <DirectXMath.h>. Ini adalah satu-satunya fungsi di pustaka yang memerlukan konten apa pun dari <windows.h> sehingga Anda tidak diharuskan untuk menyertakan <windows.h> di setiap modul yang menggunakan <DirectXMath.h>.

 

Gambaran Umum Desain

Pustaka DirectXMath terutama mendukung bahasa pemrograman C++. Pustaka diimplementasikan menggunakan rutinitas sebaris dalam file header, DirectXMath*.inl, DirectXPackedVector.inl dan DirectXCollision.inl. Implementasi ini menggunakan intrinsik kompilator berkinerja tinggi.

Pustaka DirectXMath menyediakan:

  • Implementasi menggunakan intrinsik SSE/SSE2.
  • Implementasi tanpa intrinsik.
  • Implementasi menggunakan intrinsik ARM-NEON.

Karena pustaka dikirim menggunakan file header, gunakan kode sumber untuk menyesuaikan dan mengoptimalkan aplikasi Anda sendiri.

Konvensi matriks

DirectXMath menggunakan matriks utama baris, vektor baris, dan pra-perkalian. Handedness ditentukan oleh versi fungsi mana yang digunakan (RH vs. LH), jika tidak, fungsi bekerja dengan koordinat tampilan tangan kiri atau kanan.

Sebagai referensi, Direct3D secara historis telah menggunakan sistem koordinat sebelah kiri, matriks utama baris, vektor baris, dan pra-perkalian. Direct3D Modern tidak memiliki persyaratan yang kuat untuk koordinat kiri vs. tangan kanan, dan biasanya shader HLSL default untuk mengonsumsi matriks utama kolom. Lihat Pemesanan Matriks HLSL untuk detailnya.

Penggunaan Dasar

Untuk menggunakan fungsi Pustaka DirectXMath, sertakan header DirectXMath.h, DirectXPackedVector.h, DirectXColors.h, dan/atau DirectXCollision.h. Header ditemukan di Kit Pengembangan Perangkat Lunak Windows untuk aplikasi Windows Store.

Pedoman Penggunaan Jenis

Jenis XMVECTOR dan XMMATRIX adalah kuda kerja untuk Pustaka DirectXMath. Setiap operasi mengonsumsi atau menghasilkan data dari jenis ini. Bekerja dengan mereka adalah kunci untuk menggunakan pustaka. Namun, karena DirectXMath menggunakan set instruksi SIMD, jenis data ini tunduk pada sejumlah batasan. Sangat penting bagi Anda untuk memahami pembatasan ini jika Anda ingin menggunakan fungsi DirectXMath dengan baik.

Anda harus menganggap XMVECTOR sebagai proksi untuk daftar perangkat keras SIMD, dan XMMATRIX sebagai proksi untuk pengelompokan logis empat register perangkat keras SIMD. Jenis-jenis ini dianomasikan untuk menunjukkan bahwa mereka memerlukan perataan 16-byte untuk bekerja dengan benar. Pengkompilasi akan secara otomatis menempatkannya dengan benar pada tumpukan ketika digunakan sebagai variabel lokal, atau menempatkannya di segmen data saat digunakan sebagai variabel global. Dengan konvensi yang tepat, mereka juga dapat diteruskan dengan aman sebagai parameter ke fungsi (lihat Konvensi Panggilan untuk detailnya).

Namun, alokasi dari tumpukan lebih rumit. Dengan demikian, Anda harus berhati-hati setiap kali Anda menggunakan XMVECTOR atau XMMATRIX sebagai anggota kelas atau struktur untuk dialokasikan dari tumpukan. Pada Windows x64, semua alokasi tumpukan selaras 16 byte, tetapi untuk Windows x86, mereka hanya selaras 8-byte. Ada opsi untuk mengalokasikan struktur dari tumpukan dengan perataan 16 byte (lihat Ratakan Alokasi dengan Benar). Untuk program C++, Anda dapat menggunakan operator baru/hapus/baru[]/hapus[] kelebihan beban (baik secara global atau khusus kelas) untuk memberlakukan penyelarasan optimal jika diinginkan.

Catatan

Sebagai alternatif untuk memberlakukan perataan di kelas C++ Anda secara langsung dengan membebani baru/hapus, Anda dapat menggunakan idiom pImpl. Jika Anda memastikan kelas Impl Anda selaras melalui _aligned_malloc secara internal, Anda kemudian dapat dengan bebas menggunakan jenis yang selaras dalam implementasi internal. Ini adalah opsi yang baik ketika kelas 'publik' adalah kelas ref Windows Runtime atau dimaksudkan untuk digunakan dengan std::shared_ptr<>, yang sebaliknya dapat mengganggu keselarasan yang hati-hati.

 

Namun, seringkali lebih mudah dan lebih ringkas untuk menghindari penggunaan XMVECTOR atau XMMATRIX langsung di kelas atau struktur. Sebagai gantinya, gunakan XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4, dan sebagainya, sebagai anggota struktur Anda. Selanjutnya, Anda dapat menggunakan fungsi Pemuatan Vektor dan Penyimpanan Vektor untuk memindahkan data secara efisien ke variabel lokal XMVECTOR atau XMMATRIX , melakukan komputasi, dan menyimpan hasilnya. Ada juga fungsi streaming (XMVector3TransformStream, XMVector4TransformStream, dan sebagainya) yang secara efisien beroperasi langsung pada array jenis data ini.

Membuat Vektor

VEKTOR KONSTANTA

Banyak operasi memerlukan penggunaan konstanta dalam komputasi vektor, dan ada sejumlah cara untuk memuat XMVECTOR dengan nilai yang diinginkan.

  • Jika memuat konstanta skalar ke semua elemen XMVECTOR, gunakan XMVectorReplicate atau XMVectorReplicateInt.

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • Jika menggunakan konstanta vektor dengan nilai tetap yang berbeda sebagai XMVECTOR, gunakan struktur XMVECTORF32, XMVECTORU32, XMVECTORI32, atau XMVECTORU8 . Ini kemudian dapat dirujuk langsung di mana saja Anda akan meneruskan nilai XMVECTOR .

    static const XMVECTORF32 vFactors = { 1.0f, 2.0f, 3.0f, 4.0f };
    

    Catatan

    Jangan gunakan daftar penginisialisasi langsung dengan XMVECTOR (yaitu, XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f }). Kode tersebut tidak efisien dan tidak portabel di semua platform yang didukung oleh DirectXMath.

     

  • DirectXMath mencakup sejumlah konstanta global yang telah ditentukan sebelumnya yang dapat Anda gunakan dalam kode Anda (g_XMOne, g_XMOne3, g_XMTwo, g_XMOneHalf, g_XMHalfPi, g_XMPi, dan sebagainya). Cari header DirectXMath.h untuk nilai XMGLOBALCONST .

  • Ada satu set konstanta vektor untuk warna RGB umum (Merah, Hijau, Biru, Kuning, dan sebagainya). Untuk informasi selengkapnya tentang konstanta vektor ini, lihat DirectXColors.h dan namespace DirectX::Colors.

VEKTOR DARI VARIABEL

VEKTOR DARI VEKTOR

  • Jika membuat vektor dari vektor lain dengan komponen tertentu yang diatur ke variabel, Anda dapat mempertimbangkan untuk menggunakan Fungsi Pengaktor Vektor.

    XMVECTOR v2 = XMVectorSetW( v1, fw );
    
  • Jika membuat vektor dari vektor lain dengan satu komponen yang direplikasi, gunakan XMVectorSplatX, XMVectorSplatY, XMVectorSplatZ, dan XMVectorSplatW.

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • Jika membuat vektor dari vektor atau sepasang vektor lain dengan komponen yang disusun ulang, lihat XMVectorSwizzle dan XMVectorPermute.

    XMVECTOR v2 = XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_W, XM_SWIZZLE_X>( v1 );
    
    XMVECTOR v3 = XMVectorPermute<XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_0X, XM_PERMUTE_1Z>( v1, v2 );
    

VEKTOR DARI MEMORI

Mengekstrak Komponen dari Vektor

Pemrosesan SIMD paling efisien ketika data dimuat ke dalam daftar SIMD dan diproses sepenuhnya sebelum mengekstrak hasilnya. Konversi antara bentuk skalar dan vektor tidak efisien, jadi kami sarankan Anda melakukannya hanya jika diperlukan. Untuk alasan ini, fungsi di pustaka DirectXMath yang menghasilkan nilai skalar dikembalikan dalam bentuk vektor di mana hasil skalar direplikasi di seluruh vektor yang dihasilkan (yaitu, XMVector2Dot, XMVector3Length, dan sebagainya). Namun, ketika Anda membutuhkan nilai skalar, berikut adalah beberapa pilihan tentang cara melakukannya:

  • Jika satu jawaban skalar dihitung, penggunaan Fungsi Pengaktor Vektor sesuai:

    float f = XMVectorGetX( v );
    
  • Jika beberapa komponen vektor diperlukan untuk diekstraksi, pertimbangkan untuk menyimpan vektor dalam struktur memori dan membacanya kembali. Contohnya:

    XMFLOAT4A t;
    XMStoreFloat4A( &t, v );
    // t.x, t.y, t.z, and t.w can be individually accessed now
    
  • Bentuk pemrosesan vektor yang paling efisien adalah menggunakan streaming memori-ke-memori di mana data input dimuat dari memori (menggunakan Fungsi Beban Vektor), diproses sepenuhnya dalam bentuk SIMD, dan kemudian ditulis ke memori (menggunakan Fungsi Penyimpanan Vektor).

Panduan Pemrograman DirectXMath