artemoshepkov / LearnDirectX

0 stars 0 forks source link

Splitting shader to files #4

Closed artemoshepkov closed 1 year ago

artemoshepkov commented 1 year ago

Хотелось бы разделить шейдеры на разные файлы, но компилятор этого не позволяет. После добавления инклудов в шейдер пишет следующее: Unhandled Exception: SharpDX.CompilationException: C:\Users\artem\source\repos\LearnDirectX\src\Shaders\VS.hlsl(1,10-22): error X1505: No include handler specified, can't perform a #include. Use D3DX APIs or provide your own include handler. То есть нужно включить в компиляцию шейдеров Include, но я не могу найти документации на этот счет. Нашел на с++, но не догоняю как его перевести на C# image

Altair200333 commented 1 year ago

Хотелось бы разделить шейдеры на разные файлы, но компилятор этого не позволяет. После добавления инклудов в шейдер пишет следующее: Unhandled Exception: SharpDX.CompilationException: C:\Users\artem\source\repos\LearnDirectX\src\Shaders\VS.hlsl(1,10-22): error X1505: No include handler specified, can't perform a #include. Use D3DX APIs or provide your own include handler. То есть нужно включить в компиляцию шейдеров Include, но я не могу найти документации на этот счет. Нашел на с++, но не догоняю как его перевести на C# image

Да, sharpdx не умеет в инклуды сам, ему нужно добавить хэндлер инклудов вручную прописав где-то. Это хендлер по сути будет понимать как работать с иклудом (где искать файл). Иногда в таких случаях помогает посмотреть на исходники SharpDX Связывать нативные методы на C++ и обвязку на SharpDX та ещё боль)

Как вариант можно просто вручную находить #include в файле перед компиляцией и вставлять содержимое целевого файла

Нашёл свой старый код, но я НЕ УВЕРЕН что он работает) ``` cs class ShaderTools { public static CompilationResult Compile( string shaderSource, string entryPoint, string profile, ShaderFlags shaderFlags = ShaderFlags.OptimizationLevel1, EffectFlags effectFlags = EffectFlags.None, string sourceFileName = "unknown", SecondaryDataFlags secondaryDataFlags = SecondaryDataFlags.None, DataStream secondaryData = null, Include include = null) { IntPtr num = !string.IsNullOrEmpty(shaderSource) ? Marshal.StringToHGlobalAnsi(shaderSource) : throw new ArgumentNullException(nameof(shaderSource)); try { return ShaderBytecode.Compile(num, shaderSource.Length, entryPoint, profile, shaderFlags, effectFlags, (ShaderMacro[])null, include, sourceFileName, secondaryDataFlags, secondaryData); } finally { if (num != IntPtr.Zero) Marshal.FreeHGlobal(num); } } class CustomInclude : Include { private Stream _stream; private string _directory; public CustomInclude(string directory) { _directory = directory; } public void Dispose() { _stream?.Close(); } public IDisposable Shadow { get; set; } public Stream Open(IncludeType type, string fileName, Stream parentStream) { _stream = File.Open(Path.Combine(_directory, fileName), FileMode.Open, FileAccess.Read); return _stream; } public void Close(Stream stream) { _stream?.Close(); } } public static CompilationResult CompileShader(string path, string entryPoint, string profile) { var hlslText = File.ReadAllText(path); CompilationResult shaderCompilationResult; // By default the ShaderBytecode.Compile method throws an exception when the shader cannot be compiled // But this is very annoying in debug mode, because if break on exception is turned on, we always go to Visual Studio // Therefore we disable throwing errors on compiling and check the shaderCompilationResult instead Configuration.ThrowOnShaderCompileError = false; shaderCompilationResult = ShaderBytecode.CompileFromFile(path, entryPoint, profile, include: new CustomInclude(Path.GetDirectoryName(path)));//Compile(hlslText, entryPoint, profile, include: new CustomInclude(Path.GetDirectoryName(path))); // Exception message contains the "ad-hock file name" - we try to find the "\unknown(" text and then show only the error from there on // Additional information: D:\.....\Ab3d.DirectX.ShaderFactory\bin\Debug\unknown(15,9): error X3003: redefinition of 'gDiffuseColor' if (shaderCompilationResult.ResultCode.Failure) { int pos = shaderCompilationResult.Message.IndexOf(@"\unknown("); if (pos != -1) { AddOutputErrorMessage(shaderCompilationResult.Message.Substring(pos + @"\unknown(".Length - 1)); } shaderCompilationResult = null; } return shaderCompilationResult; } public static void AddOutputErrorMessage(string msg) { Console.WriteLine(msg); } } ```