如何在SharpDX中的构建时编译顶点和像素着色器?您可以在“Direct3D Rendering Cookbook”中阅读的方法是使用HLSLCompiler.CompileFromFile。这将在运行时编译着色器,这并不总是好的。
答案 0 :(得分:2)
在最新的SharpDX 4中你可以在运行时编译像素和顶点着色器,问题是,大多数(未更新的)Windows 7都没有D3DCompiler_47.dll,它不允许你甚至运行SharpDX( SharpDX.D3DCompiler将无法使用)。最好使用DirectX SDK中的fxc在构建时编译着色器,如下所示:
ComplieShaders.bat(这个bat文件我作为项目的一部分,我在构建应用程序时调用它):
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"
奇怪的CD“%~dp0”将移动到正确的目录。我从预构建事件命令行调用此bat文件(在C#项目设置中 - >构建事件)。
这将生成二进制着色器数据,如MyVS.cso(用于顶点着色器)和MyPS.cso(用于像素着色器)。 这两个文件我再次作为内容插入到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 :(得分: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();