SDK マニュアルを見ていて HLSL Grammar の Operators に
‘##’ や ‘#@’ という演算子を発見しました。
これは本来 #define マクロの引数に適用される演算子です。
これまで Effect fx/HLSL のプリプロセッサは非常に制限された
ものだと思っていました。例えば
・#define も基本的に定数や #if 用。
・引数を伴う関数型のマクロ定義は出来ない。
などなど。
もしやと思って実際に試してみたら、なんと関数型の引数を持ったマクロも
普通に定義して使うことが出来ました。
例えば上記演算子を使ってみるとこんな感じです。
#define VARNAME(_n,_m) _n##_m #define SEMANTIC_TEX(_id) TEXCOORD##_id float VARNAME(light,ambient)= 1.0f; void VS_Main( uint vid : SV_VertexID, out float4 opos : SV_POSITION, out float2 ouv : SEMANTIC_TEX(0) ) { :
この場合 VARNAME(light,ambient) は「lightambient」と
連結された変数名になるし、SEMANTIC_TEX(0) は TEXCOORD0 に
置き換わります。
#@ は文字定数 ‘~’ への変換に相当します。例として次のように
記述してみます。
#define LCHAR(_n) #@_n int id= LCHAR(Z);
LCHAR(Z) は ‘Z’ に置き換わりました。つまり
int id= 'Z';
と等価です。
引数の文字列定数化を行う、単一の ‘#’ 演算子はありませんでした。
使えないと思っていたのでかなり驚きました。思い込んでいただけで
しょうか。
SDK Sample fx から “define” を検索しても、やはり引数を持った
関数型の define は全く使われていないようです。
試しに DirectX SDK 2006 October の fxc.exe (DX9向け) で実行したら
エラーになりました。
同じ 2006 October の fxc10.exe ではコンパイルが通ります。
D3D10 で HLSL 用プリプロセッサの機能拡張が行われたことは間違い
なさそうです。
Preprocessor は HLSL コンパイラ DLL 呼び出しとは別なので、/LD
オプションは使えませんでした。
D3D10 core API 側の Preprocessor が呼ばれると拡張タイプになり、
D3DX9 側の Preprocessor だと従来どおりの簡易型になるのではない
かと考えられます。
結論
・Direct3D10 の HLSL/Effect(fx) では、従来使えなかった関数型の
マクロ定義が使える
・さらにマクロ引数の演算子 ## と #@ も使える