[英]How can I embed and use a .txt file as resource in a C# Class Library Project (VS2012)?
[英]How can I use VS2012's automatic HLSL compiling in a C# project?
http://blogs.msdn.com/b/chuckw/archive/2012/05/07/hlsl-fxc-and-d3dcompile.aspx
上面的鏈接指出“注意:這種自動集成僅適用於C ++項目,而不適用於C#項目。” 我正在使用SlimDX,當然有一種方法可以實現,所以Visual Studio將在C#項目的構建時編譯HLSL着色器?
我想你會發現這可能會為你做到這一點。
你必須在bin文件夾中有fxc.exe directx編譯器,它可以在direct x sdk中找到。
此類提供了一個可觀察的集合,可以在WPF中用於顯示着色器配置文件列表。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Threading;
using System.Reflection;
namespace Mars.HLSLEditor
{
public class ShaderModel {
public string Key {get; set;}
public string Name { get; set; }
}
public class EffectCompiler
{
private static Dictionary<string, string> profiles = new Dictionary<string,string>();
public static ObservableCollection<shadermodel> Profiles
{
get {
var x = from p in profiles select new ShaderModel { Key = p.Key, Name = p.Value};
return new ObservableCollection<shadermodel>(x);
}
}
public static ShaderModel ProfileByKey(string key) {
return new ShaderModel { Key = key, Name = profiles[key] };
}
public static int GetProfileIndex(ShaderModel model) {
return Array.IndexOf(profiles.Keys.ToArray(), model.Key);
}
static EffectCompiler() {
profiles.Add("cs_4_0", "Compute Shader model 4.0");
profiles.Add("cs_4_1", "Compute Shader model 4.1");
profiles.Add("cs_5_0", "Compute Shader model 5.0");
profiles.Add("ds_5_0", "Domain Shader model 5.0");
profiles.Add("fx_2_0", "Effect model 2.0");
profiles.Add("fx_4_0", "Effect model 4.0");
profiles.Add("fx_4_1", "Effect model 4.1");
profiles.Add("fx_5_0", "Effect model 5.0");
profiles.Add("gs_4_0", "Geometry Shader model 4.0");
profiles.Add("gs_4_1", "Geometry Shader model 4.1");
profiles.Add("gs_5_0", "Geometry Shader model 5.0");
profiles.Add("hs_5_0", "Hull Shader model 5.0");
profiles.Add("ps_2_0", "Pixel Shader model 2.0");
profiles.Add("ps_2_a", "Pixel Shader model 2.0 A");
profiles.Add("ps_2_b", "Pixel Shader model 2.0 B");
profiles.Add("ps_2_sw", "Pixel Shader model 2.0 (software)");
profiles.Add("ps_3_0", "Pixel Shader model 3.0");
profiles.Add("ps_3_sw", "Pixel Shader model 3.0 (software)");
profiles.Add("ps_4_0", "Pixel Shader model 4.0");
profiles.Add("ps_4_0_level_9_0", "Pixel Shader model 4.0 (level 9.0)");
profiles.Add("ps_4_0_level_9_1", "Pixel Shader model 4.0 (level 9.1)");
profiles.Add("ps_4_0_level_9_3", "Pixel Shader model 4.0 (level 9.3)");
profiles.Add("ps_4_1", "Pixel Shader model 4.1");
profiles.Add("ps_5_0", "Pixel Shader model 5.0");
profiles.Add("tx_1_0", "Texture Shader model 1.0 (software)");
profiles.Add("vs_1_1", "Vertex Shader model 1.1");
profiles.Add("vs_2_0", "Vertex Shader model 2.0");
profiles.Add("vs_2_a", "Vertex Shader model 2.0 A");
profiles.Add("vs_2_sw", "Vertex Shader model 2.0 (software)");
profiles.Add("vs_3_0", "Vertex Shader model 3.0");
profiles.Add("vs_3_sw", "Vertex Shader model 3.0 (software)");
profiles.Add("vs_4_0", "Vertex Shader model 4.0");
profiles.Add("vs_4_0_level_9_0", "Vertex Shader model 4.0 (level 9.0)");
profiles.Add("vs_4_0_level_9_1", "Vertex Shader model 4.0 (level 9.1)");
profiles.Add("vs_4_0_level_9_3", "Vertex Shader model 4.0 (level 9.3)");
profiles.Add("vs_4_1", "Vertex Shader model 4.1");
profiles.Add("vs_5_0", "Vertex Shader model 5.0");
}
static object locker = new object();
public static bool TryCompile(string code, ShaderModel model, string entrypoint, out string error) {
lock (locker)
{
string id = Thread.CurrentThread.ManagedThreadId.ToString();
string path = string.Format("{0}\\tmp{1}.fx", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), id);
using (FileStream fs = new FileStream(path, FileMode.Create))
{
byte[] data = Encoding.ASCII.GetBytes(code);
fs.Write(data, 0, data.Length);
}
string fxc = Path.Combine(new Uri(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase)).AbsolutePath, @"fxc.exe");
if (!File.Exists(fxc))
{
error = "No effect compiler executable!";
return false;
}
ProcessStartInfo psi = new ProcessStartInfo(fxc);
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.Arguments = string.Format("/T {1} /E {2} /Fo\"{0}.obj\" \"{0}\"", path, model.Key, entrypoint);
error = string.Empty;
using (Process p = Process.Start(psi))
{
StreamReader sr = p.StandardError;
error = sr.ReadToEnd().Replace(path, "Line ");
if (!p.WaitForExit(5000))
{
error = "General failure while compiling (timeout).";
return false;
}
}
if (File.Exists(path))
File.Delete(path);
if (File.Exists(path + ".obj"))
File.Delete(path + ".obj");
if (error == string.Empty)
{
return true;
}
error = error.Replace("compilation failed; no code produced", "");
error = error.Trim();
return false;
}
}
}
}
此代碼屬於火星 :(他真的應該收到賞金) http://marscode.blogspot.com.au/2011/04/directx-xna-shader-test-compiler-in-c.html
這是另一個有用的資源:
它展示了如何在System.Windows.Media.Effects Namespace
使用public abstract class ShaderEffect : Effect
for C#
他提到public class EffectCompiler
http://msdn.microsoft.com/library/windows/desktop/bb232919(v=vs.85).aspx
編輯:
請包括
using System.IO;
之前
using System.Windows.Shapes;
它會拋出一個錯誤,但它會按此順序工作,並帶有警告,它仍會編譯。 使用Path
和兩個名稱空間存在歧義。
請告知是否可以解決您的問題。
沒有簡單的方法可以將HLSL的Visual C ++ MSBuild規則添加到C#項目中。 通常,您必須使用自定義構建步驟,或者如在StackOverflow上的其他位置所建議的那樣,您可以在解決方案中創建一個僅構建着色器的C ++項目。
您可以手動將3D資產和內容支持添加到C#項目,就像在Stenning的Direct3D渲染手冊中為代碼所做的那樣,以獲得DDS,FBX-> CMO和DGSL着色器管道支持。 你可以在GitHub上看到這些項目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.