Bagikan melalui


Mengkompilasi Efek (Direct3D 11)

Setelah efek ditulis, langkah selanjutnya adalah mengkompilasi kode untuk memeriksa masalah sintaks.

Anda melakukannya dengan memanggil salah satu API kompilasi (D3DX11CompileFromFile, D3DX11CompileFromMemory, atau D3DX11CompileFromResource ). API ini memanggil pengkompilasi efek fxc.exe, yang mengkompilasi kode HLSL. Inilah sebabnya mengapa sintaks untuk kode dalam efek terlihat sangat mirip dengan kode HLSL. (Ada beberapa pengecualian yang akan ditangani nanti). Pengkompilasi efek/pengkompilasi hlsl, fxc.exe, tersedia di SDK di folder utilitas sehingga shader (atau efek) dapat dikompilasi secara offline jika Anda memilih. Lihat dokumentasi untuk menjalankan pengkompilasi dari baris perintah.

Contoh

Berikut adalah contoh kompilasi file efek.

WCHAR str[MAX_PATH];
DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );

hr = D3DX11CompileFromFile( str, NULL, NULL, pFunctionName, pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL, NULL, &pBlob, &pErrorBlob, NULL );

Mencakup

Salah satu parameter API kompilasi adalah antarmuka yang disertakan. Hasilkan salah satu dari ini jika Anda ingin menyertakan perilaku yang disesuaikan saat pengompilasi membaca file sertakan. Pengkompilasi menjalankan perilaku kustom ini setiap kali membuat atau mengkompilasi efek (yang menggunakan penunjuk include). Untuk mengimplementasikan perilaku include yang disesuaikan, dapatkan kelas dari antarmuka ID3DInclude . Ini memberi kelas Anda dua metode: Buka dan Tutup. Terapkan perilaku kustom dalam metode ini.

Mencari Sertakan File

Penunjuk yang diteruskan pengkompilasi dalam parameter pParentData ke metode Buka handler include Anda mungkin tidak menunjuk ke kontainer yang menyertakan file #include yang dibutuhkan pengkompilasi untuk mengkompilasi kode shader Anda. Artinya, pengkompilasi mungkin melewati NULL di pParentData. Oleh karena itu, kami sarankan anda menyertakan handler mencari daftarnya sendiri dari menyertakan lokasi untuk konten. Handler Anda termasuk dapat secara dinamis menambahkan lokasi penyertaan baru karena menerima lokasi tersebut dalam panggilan ke metode Buka .

Dalam contoh berikut, misalkan kode shader menyertakan file keduanya disimpan di direktori somewhereelse . Ketika pengkompilasi memanggil metode Buka include handler untuk membuka dan membaca konten somewhereelse\foo.h, handler include dapat menyimpan lokasi direktori somewhereelse . Kemudian, ketika pengkompilasi memanggil metode Buka include handler untuk membuka dan membaca konten bar.h, handler include dapat secara otomatis mencari di direktori somewhereelse untuk bar.h.

Main.hlsl:
#include "somewhereelse\foo.h"

Foo.h:
#include "bar.h"

Makro

Kompilasi efek juga dapat membawa penunjuk ke makro yang ditentukan di tempat lain. Misalnya, Anda ingin mengubah efek di BasicHLSL10, untuk menggunakan dua makro: nol dan satu. Kode efek yang menggunakan dua makro diperlihatkan di sini.

if( bAnimate )
    vAnimatedPos += float4(vNormal, zero) *  
        (sin(g_fTime+5.5)+0.5)*5;
        
    Output.Diffuse.a = one;         

Berikut adalah deklarasi untuk dua makro.

D3D10_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };

Makro adalah array makro yang dihentikan NULL; di mana setiap makro didefinisikan dengan menggunakan struct D3D10_SHADER_MACRO .

Ubah panggilan efek kompilasi untuk mengambil penunjuk ke makro.

D3DX11CompileFromFile( str, Shader_Macros, NULL, pFunctionName, 
                       pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL, 
                       NULL, &pBlob, &pErrorBlob, NULL );    

Bendera Shader HLSL

Bendera shader menentukan batasan shader ke pengkompilasi HLSL. Bendera ini memengaruhi kode yang dihasilkan oleh pengkompilasi shader dengan cara berikut:

  • Optimalkan ukuran kode.
  • Termasuk informasi debug, yang mencegah kontrol aliran.
  • Mempengaruhi target kompilasi dan apakah shader dapat berjalan pada perangkat keras warisan.

Bendera ini dapat digabungkan secara logis jika Anda belum menentukan dua karakteristik yang bertentangan. Untuk daftar bendera, lihat konstanta D3D10_SHADER.

Bendera FX

Gunakan bendera ini saat Anda membuat efek untuk menentukan perilaku kompilasi atau perilaku efek runtime. Untuk daftar bendera, lihat konstanta D3D10_EFFECT.

Memeriksa Kesalahan

Jika selama kompilasi terjadi kesalahan, API mengembalikan antarmuka yang berisi kesalahan dari pengkompilasi efek. Antarmuka ini disebut ID3DBlob. Ini tidak dapat dibaca secara langsung; namun, dengan mengembalikan penunjuk ke buffer yang berisi data (yang merupakan string), Anda dapat melihat kesalahan kompilasi apa pun.

Contoh ini berisi kesalahan dalam BasicHLSL.fx, deklarasi variabel pertama terjadi dua kali.

//-------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------
float4 g_MaterialAmbientColor;      // Material's ambient color

// Declare the same variable twice
float4 g_MaterialAmbientColor;      // Material's ambient color

Kesalahan ini menyebabkan pengkompilasi mengembalikan kesalahan berikut, seperti yang ditunjukkan pada cuplikan layar jendela Watch berikut di Microsoft Visual Studio.

cuplikan layar jendela watch visual studio dengan kesalahan 0x01997fb8

Karena compiler mengembalikan kesalahan dalam pointer LPVOID, transmisikan ke string karakter di jendela Watch.

Berikut adalah kode yang mengembalikan kesalahan dari kompilasi yang gagal.

// Read the D3DX effect file
WCHAR str[MAX_PATH];
ID3DBlob*   l_pBlob_Effect = NULL;
ID3DBlob*   l_pBlob_Errors = NULL;
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX11CompileFromFile( str, NULL, NULL, pFunctionName, 
                       pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL, 
                       NULL, &pBlob, &pErrorBlob, NULL );      

LPVOID l_pError = NULL;
if( pErrorBlob )
{
    l_pError = pErrorBlob->GetBufferPointer();
    // then cast to a char* to see it in the locals window
}

Merender Efek (Direct3D 11)