2017-08-04 4 views
2

Comment compiler des vertex et des pixel shaders lors de la construction dans SharpDX? La façon dont vous pouvez lire dans "Direct3D Rendering Cookbook" est d'utiliser HLSLCompiler.CompileFromFile. Cela va compiler les shaders à l'exécution, ce qui n'est pas toujours bon.Shades de compilation SharpDX

Répondre

2

Dans le dernier SharpDX 4, vous pouvez compiler pixel et vertex shader à l'exécution, le problème est, la plupart des (non mis à jour) Windows 7 n'ont pas D3DCompiler_47.dll, qui ne vous permettra même pas d'exécuter le SharpDX (SharpDX.D3DCompiler ne sera pas disponible). Il est préférable d'utiliser FXC de DirectX SDK pour compiler les shaders au moment de la construction comme suit:

ComplieShaders.bat (ce fichier chauve-souris, j'ai comme une partie du projet et je l'appelle lors de la construction app):

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" 

Le cd étrange "% ~ dp0" se déplace vers le répertoire correct. Ce fichier chauve-souris que j'appelle depuis la ligne de commande de l'événement Pré-construction (dans les paramètres du projet C# -> Construire les événements).

Cela produira des données de shaders binaires comme MyVS.cso (pour vertex shader) et MyPS.cso (pour pixel shader). Ces deux fichiers sont de nouveau insérés en tant que projet Content to C#.

Ensuite, vous pouvez utiliser les deux fichiers en 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)); 

Si vous avez des problèmes pour trouver votre fichier MyVS.cso dans votre application C#, vous pouvez utiliser assembly.GetManifestResourceNames() pour obtenir la liste de tout le contenu disponible fichiers en assemblage (avec chemin complet).

1

Eh bien, j'ai découvert, la façon ci-dessus n'est pas bon pour le déploiement. Le problème est, les fichiers de contenu sont situés en dehors de exe ou dll, donc je les utilise plutôt comme "Embedded Resource" - de cette façon les fichiers cso sont intégrés dans l'assembly (dll ou exe). Pour charger le flux pour une utilisation des ressources intégrées:

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; 
    } 

Pour obtenir le chemin/identifiant de ressource (il peut être assez long), vous pouvez utiliser:

var assembly = Assembly.GetExecutingAssembly(); 
string[] resources = assembly.GetManifestResourceNames();