c# - C# SharpDX compilefromfile 与嵌入式资源
问题描述
您好,我现在有一些文件是嵌入式资源,但问题是使用:
CompilationResult result = SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(
fileName,
entryPoint,
profile,
shaderFlags,
include: FileIncludeHandler.Default,
defines: defines);
把错误:
System.IO.FileNotFoundException: 'Unable to find file'
。我发现还有其他从源代码编译的函数:
CompilationResult result = SharpDX.D3DCompiler.ShaderBytecode.Compile(data,profile,shaderFlags);
要从嵌入式资源文件中读取,我使用这个小类:链接 1
用法如下所示:
string data = ResourceHelper.GetEmbeddedResource(fileName);
CompilationResult result = SharpDX.D3DCompiler.ShaderBytecode.Compile(data,profile,shaderFlags);
但现在我得到这个错误:
System.ArgumentNullException: 'Value cannot be null.
Parameter name: entryPoint'
为了检查应用程序是否加载了所有嵌入资源,我使用了这个小方法,它返回所有嵌入资源
string[] zz = Assembly.GetExecutingAssembly().GetManifestResourceNames();
MessageBox.Show(string.Join("\n", zz));
我在这里缺少什么?
编辑1:
这是我如何使用它的完整方法:
public static ShaderBytecode CompileShader(string fileName, string entryPoint, string profile, ShaderMacro[] defines = null)
{
var shaderFlags = ShaderFlags.None;
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(fileName))
{
using (var reader = new StreamReader(stream))
{
CompilationResult result = SharpDX.D3DCompiler.ShaderBytecode.Compile(reader.ReadToEnd(),entrypoint,profile,shaderFlags);
/*CompilationResult result = SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(
fileName,
entryPoint,
profile,
shaderFlags,
include: FileIncludeHandler.Default,
defines: defines);*/
return new ShaderBytecode(result);
}
}
}
实际用法:
string MainName = "my_project";
_shaders["standardVS"] = D3DUtility.CompileShader(MainName+".Shaders.Default.hlsl", "VS", "vs_5_1");
//50 other files...
编辑 2: 向 Compile 方法添加了入口点,但现在它抛出错误:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
在:
return new ShaderBytecode(result);
执行处理程序显示了这一点:
Message="C\FileLocation: error X1505: No include handler specified, can't perform a #include. Use D3DX APIs or provide your own include handler.\n"
编辑 3:使用@J。van Langen 更新了它显示的方法,如下所示:
System.Exception: 'C:\Users\test\source\repos\myapp\Debug\Resources\DemoScene\unknown(14,10-30): error X1505: No include handler specified, can't perform a #include. Use D3DX APIs or provide your own include handler.'
result.Message = result.Message="error CS0452: The type 'ShaderBytecode' must be a reference type in order to use it as parameter 'T' in the generic type or method 'CompilationResultBase<T>'"
编辑 4:我想我找到了为什么它的抛出错误,因为它包含在其中: Pastebin
解决方案
您不应该使用CompileFromFile
,但Compile
也需要重载,Compile(string shaderSource, string entryPoint, string profile, ShaderFlags shaderFlags, .....
其余参数使用默认值。
这是我做过的一个旧项目的一个例子:
static GradientRenderer()
{
// This may be changed to GetType() (see 'The new reflection API')
var assembly = typeof(GradientRenderer).GetTypeInfo().Assembly;
//string[] resources = assembly.GetManifestResourceNames();
string code;
// use the full filename with namespace
using (var stream = assembly.GetManifestResourceStream("MirageDX11.Renderers.Gradient.Gradient.hlsl"))
using (var reader = new StreamReader(stream))
// read the whole content to a string.
code = reader.ReadToEnd();
var shaderFlags = ShaderFlags.None;
#if DEBUG
shaderFlags |= ShaderFlags.Debug;
shaderFlags |= ShaderFlags.SkipOptimization;
#endif
// Compile the vertex shader and the pixel shader "VS" & "PS" => entrypoint
_vertexShaderByteCode = ShaderBytecode.Compile(code, "VS", "vs_5_0", shaderFlags);
_pixelShaderByteCode = ShaderBytecode.Compile(code, "PS", "ps_5_0", shaderFlags);
}
这是着色器
struct VertexIn
{
float3 PosL : POSITION;
float4 Color : COLOR;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float4 Color: COLOR;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout.PosH = float4(vin.PosL, 1.0f);
vout.Color = vin.Color;
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
float4 value = pin.Color;
value.w = 1.0f;
return value;
}
关于如何捕获着色器错误的更新:
我已经修改了您的方法来捕获着色器编译错误。它将引发带有有用消息的异常。
public static ShaderBytecode CompileShader(string fileName, string entryPoint, string profile, ShaderMacro[] defines = null)
{
var shaderFlags = ShaderFlags.None;
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(fileName))
{
using (var reader = new StreamReader(stream))
{
CompilationResult result = SharpDX.D3DCompiler.ShaderBytecode.Compile(reader.ReadToEnd(),entrypoint,profile,shaderFlags);
// when the Bytecode == null, means that an error has occurred
if (result.Bytecode == null)
throw new InvalidOperationException(result.Message);
// removed old code in comment...
return new ShaderBytecode(result);
}
}
}
推荐阅读
- node.js - create-react-app 后无法启动项目:错误:找不到模块“C:\Users\pcname\Documents\react-scripts\bin\react-scripts.js”
- mysql - 仅当子表中的外键在父表中具有分配给它的值时,才在子表中创建条目
- javascript - 如何使用按键阻止我的形状移动?
- json - 如何使用 Dart 中属性名称的枚举将 JSON 映射到对象
- xamarin.ios - 导航控制器设置为空,使用 UITabBarController
- python - Selenium/python - “查找部分链接文本”和“xpath”
- html - CSS z-index 谜题
- node.js - MEAN - 未找到 Http Put 请求 404
- python - 使用另一个列表测试列表的内容
- postgresql - PostgreSQL 12 可以在执行时使用子查询返回列表进行分区修剪吗?