2017-08-04 3 views
2

SharpDXでビルド時に頂点シェーダとピクセルシェーダをコンパイルするにはどうすればいいですか? 「Direct3D Rendering Cookbook」で読むことができる方法は、HLSLCompiler.CompileFromFileを使用することです。これは実行時にシェイダーをコンパイルしますが、必ずしも良いとは限りません。SharpDXシェーダをコンパイル

答えて

2

最新のSharpDX 4では、実行時にピクセルと頂点シェーダをコンパイルすることができますが、問題は、Windows 7にはD3DCompiler_47.dllがないため、SharpDXを実行することができません(SharpDX.D3DCompilerは利用できません)。これは次のようにビルド時にシェーダをコンパイルするにはDirectX SDKからFXCを使用することをお勧めします:

ComplieShaders.bat(このbatファイルIは、プロジェクトの一部として持っており、アプリケーションを構築するとき、私はそれを呼び出す):

Echo Building shaders 
Echo Launch dir: "%~dp0" 
Echo Current dir: "%CD%" 
cd "%~dp0" 
PATH="c:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\" 
fxc /T vs_5_0 /E VSMain "Laser.hlsl" /Fo "MyVS.cso" 
fxc /T ps_5_0 /E PSMain "Laser.hlsl" /Fo "MyPS.cso" 

"%〜dp0"という奇妙なCDが正しいディレクトリに移動します。ビルド前のイベントコマンドライン(C#プロジェクト設定 - >ビルドイベント)から呼び出すこのバットファイル。

これにより、MyVS.cso(頂点シェーダ用)とMyPS.cso(ピクセルシェーダ用)のバイナリシェーダデータが生成されます。 これらの2つのファイルをコンテンツとしてC#プロジェクトに再度挿入します。

その後は、C#で両方のファイルを使用することができます。

string shaderFile = @"SomeDirectoryInYourApp\Shaders\MyVS.cso"; 
    if (!Path.IsPathRooted(shaderFile)) 
    { 
     shaderFile = Path.Combine(System.IO.Path.GetDirectoryName(
      System.Reflection.Assembly.GetEntryAssembly().Location), 
     shaderFile); 
    } 

    using (var shaderCodeReader = new System.IO.StreamReader(shaderFile)) 
    { 
     vertexShaderBytecode = ToDispose(ShaderBytecode.FromStream(
      shaderCodeReader.BaseStream)); 
    } 

    vertexShader = ToDispose(new VertexShader(device, vertexShaderBytecode)); 

あなたは問題があなたのC#のアプリでMyVS.csoファイルを見つけることがある場合は、すべての利用可能なコンテンツのリストを取得するにはassembly.GetManifestResourceNamesを()を使用することができますアセンブリ内のファイル(完全なパス)。

1

私は、上記の方法はデプロイメントには適していないことを知りました。問題は、コンテンツファイルがexeまたはdllの外部にあるため、私はむしろそれらを "組み込みリソース"として使用することです。このようにして、csoファイルはアセンブリ(dllまたはexe)に埋め込まれます。埋め込みリソースの使用のためのストリームをロードするには:

protected SharpDX.D3DCompiler.ShaderBytecode LoadShaderFromManifestResourceFile(
      System.Reflection.Assembly assembly, string resourceName) 
    { 
     SharpDX.D3DCompiler.ShaderBytecode shaderBytecode = null; 

     using (var shaderCodeReader = assembly.GetManifestResourceStream(resourceName)) 
     { 
      shaderBytecode = ToDispose(ShaderBytecode.FromStream(shaderCodeReader)); 
     } 

     return shaderBytecode; 
    } 

が(それはかなり長くなる可能)リソースパス/識別子を取得するには、使用することができます。

var assembly = Assembly.GetExecutingAssembly(); 
string[] resources = assembly.GetManifestResourceNames(); 
関連する問題