Direct3D 10 の ShaderModel4.0 は非常に自由度が高く、かなりいろいろな
ことができます。3.0 以前の制約の中で結構がんばってコードを書いた経験が
あるなら、この柔軟性にはちょっとした感動を覚えるかもしれません。
特にマニュアルを読んでいて衝撃を受けたのがこれ
・Using the Input-Assembler Stage without Buffers (Direct3D 10)
マニュアルの下記の場所にあります。
+ DirectX Graphics
+ Direct3D 10
+ Programming Guide
+ Pipeline Stages
+ Input-Assembler Stage
+ Getting Started with the Input-Assembler Stage
+ Using the Input-Assembler Stage without Buffers (Direct3D 10)
SV_VertexID を元に VertexShader の中で頂点を選択して描画しています。
つまり、VertexBuffer も IndexBuffer も無く、InputLayout も設定せずに
ポリゴンが描画できてしまうのです。
このシンプルさに惚れました。
自分でも同じように、頂点バッファ無しにポリゴン描画できるシェーダーを
作ってみました。fx を読み込んで描画するだけで、一切リソースを作らなくても
こんな感じの Cube を表示することができます。
形状を生成しているのは下記の部分です。
ついにシェーダーでこんなトリッキーなコードが走るようになりました。
float3 VS_Main( uint id : SV_VertexID, uint sid : SV_InstanceID ) : POSITION
{
uint _map[]= {
101733320,
104889305,
56280874,
125360034,
};
id= _map[id&3]>>(((id&60)>>2)*3);
float3 pos;
pos.x= id & 1 ? 1 : -1;
pos.y= id & 2 ? -1 : 1;
pos.z= id & 4 ? 1 : -1;
float2 ss;
sincos( sid * 0.5236f, ss.x, ss.y );
pos.xy+= ss * 5;
return mul( float4( pos, 1 ), WorldToView ).xyz;
}
シェーダー全部でもこれだけです。
・cube.fx
描画している C++ 側はこんな感じです。
g_iEffect->GetTechniqueByIndex( 0 )->GetPassByIndex( 0 )->Apply( 0 );
g_iDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
g_iDevice->DrawInstanced( 36, 12, 0, 0 );
g_iSwapChain->Present( 0, 0 );
ソースリストと実行ファイルは
・「HYPERでんち」 オリジナルサンプルプログラム
に掲載しましたので、興味ある方がいましたらどうぞお試しください。