/// <summary> /// 初期化 /// </summary> /// <param name="data"></param> public void Initialize(byte[] data) { var device = GraphicsCore.D3D11Device; // byte配列からポインタを取得 var handle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); BinaryHeader header = (BinaryHeader)Marshal.PtrToStructure(ptr, typeof(BinaryHeader)); IntPtr vs_ptr = ptr + (int)header.vs_offset; IntPtr ps_ptr = ptr + (int)header.ps_offset; name_ = "0x" + header.id.ToString("x8"); shaderId_ = header.id; // 頂点シェーダ using (ShaderBytecode bytecode = new ShaderBytecode(new SlimDX.DataStream(vs_ptr, header.vs_size, true, false))) { vertexShader_ = new VertexShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // レイアウト生成 vertexAttr_ = reflect.GetVertexLayoutAttribute(); int layout_id = Shader.GetVertexLayoutID(vertexAttr_); inputLayout_ = new InputLayout(device, bytecode, sLayoutList[layout_id]); // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ピクセルシェーダ using (ShaderBytecode bytecode = new ShaderBytecode(new SlimDX.DataStream(ps_ptr, header.ps_size, true, false))) { pixelShader_ = new PixelShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ハンドル解放 handle.Free(); Initilaized = true; }
/// <summary> /// 初期化 /// </summary> /// <param name="data"></param> public void Initialize(InitDesc desc) { var device = GraphicsCore.D3D11Device; shaderId_ = desc.id; name_ = desc.name; if (desc.file_name != null) { // ファイルから生成 // バイナリキャッシング string cacheDir = System.IO.Path.GetDirectoryName(desc.file_name) + "/cache"; if (!System.IO.Directory.Exists(cacheDir)) { System.IO.Directory.CreateDirectory(cacheDir); } string cacheFile = cacheDir + "/" + desc.name + "_" + desc.vs_main + "_" + desc.ps_main; string vsCacheFile = cacheFile + ".vsc"; string psCacheFile = cacheFile + ".psc"; // 頂点シェーダキャッシュ読み取り ShaderBytecode vsBytecode = null; if (System.IO.File.Exists(vsCacheFile)) { DateTime cacheTime = System.IO.File.GetLastWriteTime(vsCacheFile); DateTime editTime = System.IO.File.GetLastWriteTime(desc.file_name); if (cacheTime > editTime) { System.IO.FileStream stream = new System.IO.FileStream(vsCacheFile, FileMode.Open); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, (int)stream.Length); vsBytecode = new ShaderBytecode(new SlimDX.DataStream(bytes, true, false)); } } // キャッシュになければコンパイルして生成 ShaderIncludeHandler inc = null; if (vsBytecode == null) { inc = new ShaderIncludeHandler(System.IO.Path.GetDirectoryName(desc.file_name)); vsBytecode = ShaderBytecode.CompileFromFile(desc.file_name, desc.vs_main, "vs_" + desc.profile, ShaderFlags.None, EffectFlags.None, desc.macro, inc); // キャッシュファイル保存 System.IO.FileStream stream = new System.IO.FileStream(vsCacheFile, FileMode.Create); vsBytecode.Data.CopyTo(stream); stream.Close(); } using (vsBytecode) { vertexShader_ = new VertexShader(device, vsBytecode); using (ShaderReflection reflect = new ShaderReflection(vsBytecode)) { vertexAttr_ = reflect.GetVertexLayoutAttribute(); int layout_id = Shader.GetVertexLayoutID(vertexAttr_); var signeture = ShaderSignature.GetInputSignature(vsBytecode); inputLayout_ = new InputLayout(device, signeture, sLayoutList[layout_id]); signeture.Dispose(); // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ピクセルシェーダキャッシュ読み取り if (desc.ps_main != null) { ShaderBytecode psBytecode = null; if (System.IO.File.Exists(psCacheFile)) { DateTime cacheTime = System.IO.File.GetLastWriteTime(psCacheFile); DateTime editTime = System.IO.File.GetLastWriteTime(desc.file_name); if (cacheTime > editTime) { System.IO.FileStream stream = new System.IO.FileStream(psCacheFile, FileMode.Open); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, (int)stream.Length); psBytecode = new ShaderBytecode(new SlimDX.DataStream(bytes, true, false)); } } if (psBytecode == null) { if (inc == null) { inc = new ShaderIncludeHandler(System.IO.Path.GetDirectoryName(desc.file_name)); } psBytecode = ShaderBytecode.CompileFromFile(desc.file_name, desc.ps_main, "ps_" + desc.profile, ShaderFlags.None, EffectFlags.None, desc.macro, inc); // キャッシュファイル保存 System.IO.FileStream stream = new System.IO.FileStream(psCacheFile, FileMode.Create); psBytecode.Data.CopyTo(stream); stream.Close(); } using (psBytecode) { pixelShader_ = new PixelShader(device, psBytecode); using (ShaderReflection reflect = new ShaderReflection(psBytecode)) { // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } } } else { // stringから生成 // 頂点シェーダ using (var bytecode = ShaderBytecode.Compile(desc.vs_string, desc.vs_main, "vs_" + desc.profile, ShaderFlags.None, EffectFlags.None)) { vertexShader_ = new VertexShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { vertexAttr_ = reflect.GetVertexLayoutAttribute(); int layout_id = Shader.GetVertexLayoutID(vertexAttr_); var signeture = ShaderSignature.GetInputSignature(bytecode); inputLayout_ = new InputLayout(device, signeture, sLayoutList[layout_id]); signeture.Dispose(); // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } // ピクセルシェーダ if (desc.ps_main != null) { using (var bytecode = ShaderBytecode.Compile(desc.ps_string, desc.ps_main, "ps_" + desc.profile, ShaderFlags.None, EffectFlags.None)) { pixelShader_ = new PixelShader(device, bytecode); using (ShaderReflection reflect = new ShaderReflection(bytecode)) { // コンスタントバッファ解決 ResolveConstantBuffer(reflect); } } } } Initilaized = true; }