Mengkompilasi Efek (Direct3D 10)
Setelah efek ditulis, langkah pertama adalah mengkompilasi kode untuk memeriksa masalah sintaks. Ini dilakukan dengan memanggil salah satu API kompilasi (seperti D3DX10CompileEffectFromFile, D3DX10CompileEffectFromResource, D3DX10CompileEffectFromMemory). API ini memanggil pengkompilasi efek fxc.exe yang merupakan pengkompilasi yang digunakan untuk mengkompilasi kode HLSL. Inilah sebabnya mengapa sintaks untuk kode dalam efek terlihat sangat mirip dengan kode HLSL (ada beberapa pengecualian yang akan ditangani nanti). Ngomong-ngomong, pengkompilasi efek/pengkompilasi hlsl (fxc.exe) ada di SDK di folder utilitas sehingga Anda dapat mengkompilasi shader (atau efek) secara offline jika Anda memilih. Lihat dokumentasi untuk menjalankan pengkompilasi dari baris perintah.
Berikut adalah contoh kompilasi file efek (dari sampel BasicHLSL10).
WCHAR str[MAX_PATH];
DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX10CompileEffectFromFile( str, NULL, NULL, "fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL,
&l_pBlob_Effect, &l_pBlob_Errors, NULL );
Mencakup
Salah satu parameter adalah antarmuka yang disertakan. Hasilkan salah satu dari ini jika Anda ingin menyertakan perilaku yang disesuaikan saat membaca file sertakan. Perilaku kustom ini dijalankan setiap kali efek (yang menggunakan penunjuk sertakan) dibuat atau ketika efek (yang menggunakan penunjuk sertakan) dikompilasi. Untuk mengimplementasikan perilaku yang disesuaikan termasuk, dapatkan kelas dari antarmuka Sertakan. Ini menyediakan dua metode kelas Anda: Buka dan Tutup. Terapkan perilaku kustom dalam metode Buka dan Tutup.
Makro
Kompilasi efek juga dapat mengambil penunjuk ke makro yang ditentukan di tempat lain. Misalnya, Anda memodifikasi 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.
D3D_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };
Makro adalah array makro null yang dihentikan; di mana setiap makro didefinisikan dengan struct D3D_SHADER_MACRO .
Terakhir, ubah panggilan efek kompilasi untuk mengambil penunjuk ke makro.
D3DX10CreateEffectFromFile( str, Shader_Macros, NULL,
D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL,
&g_pEffect10, NULL );
Bendera Shader HLSL
Bendera shader menentukan batasan shader ke pengkompilasi HLSL. Bendera ini berdampak pada kode yang dihasilkan oleh pengkompilasi shader termasuk:
- Pertimbangan ukuran: optimalkan kode.
- Pertimbangan debug: termasuk informasi debug, mencegah kontrol alur.
- Pertimbangan perangkat keras: target kompilasi dan apakah shader dapat berjalan pada perangkat keras warisan atau tidak.
Secara umum, bendera ini dapat digabungkan secara logis, dengan asumsi Anda belum menentukan dua karakteristik yang bertentangan. Untuk daftar bendera lihat Konstanta Efek (Direct3D 10).
Bendera FX
Bendera ini digunakan saat membuat efek untuk menentukan perilaku kompilasi atau perilaku efek runtime. Untuk daftar bendera lihat Konstanta Efek (Direct3D 10).
Memeriksa Kesalahan
Jika selama kompilasi, terjadi kesalahan, API mengembalikan antarmuka yang berisi kesalahan yang dikembalikan dari pengkompilasi efek. Antarmuka ini disebut ID3D10Blob. Namun, ini tidak dapat dibaca secara langsung, dengan mengembalikan penunjuk ke buffer yang berisi data (yang merupakan string), Anda dapat melihat kesalahan kompilasi apa pun.
Dalam contoh ini, kesalahan dimasukkan ke dalam efek BasicHLSL.fx dengan menyalin deklarasi variabel pertama 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.
Karena kesalahan dikembalikan dalam penunjuk LPVOID, transmisikan ke string karakter di jendela watch.
Berikut adalah kode yang digunakan untuk mengembalikan kesalahan dari kompilasi yang gagal.
// Read the D3DX effect file
WCHAR str[MAX_PATH];
ID3D10Blob* l_pBlob_Effect = NULL;
ID3D10Blob* l_pBlob_Errors = NULL;
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX10CompileEffectFromFile( str, NULL, NULL,
D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL,
&l_pBlob_Effect, &l_pBlob_Errors );
LPVOID l_pError = NULL;
if( l_pBlob_Errors )
{
l_pError = l_pBlob_Errors->GetBufferPointer();
// then cast to a char* to see it in the locals window
}
Topik terkait