2016-02-03 79 views
0

我一直在試圖讓常量/紋理緩衝區在SharpDX中工作(它就像SlimDX),但我放入它的數據似乎並沒有進入着色器。SharpDX常量/紋理緩衝區不工作

我擡頭看了如何做到這一點,並遵循例子,但我不能得到它的工作。

最終,我需要能夠在我的着色器中輸入多個不同數據類型的大型數組,所以如果任何人都可以給我一個可以做到的工作示例,那就太好了!

但是現在我已經寫了一個簡單的例子,我試圖去測試,而我卻無法完成它的工作。通常我可以在繪製三角形時至少顯示某些內容,但現在它甚至不會這樣做。

這可能是我忽略的一個愚蠢的錯誤,但無論如何,如果有人可以只是看看它,指出什麼是錯的,或者更好的,修復它併發布更新的代碼(它是完整的,應該編譯)。

如果代碼很長,我很抱歉,但我試圖儘可能簡化代碼。無論如何,那就是:

using SharpDX; 
using SharpDX.Direct3D; 
using SharpDX.Direct3D11; 
using SharpDX.DXGI; 
using SharpDX.Windows; 
using SharpDX.D3DCompiler; 
using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace test_namespace 
{ 
    class Test 
    { 
     [StructLayout(LayoutKind.Explicit, Size = 80, Pack = 16)] 
     public struct Data 
     { 
      [FieldOffset(0)] 
      public Matrix mat; 
      [FieldOffset(64)] 
      public Vector4 testColor; 
     } 

     [StructLayout(LayoutKind.Explicit)] 
     public struct Point 
     { 
      [FieldOffset(0)] 
      public Vector4 pos; 
      [FieldOffset(16)] 
      public Vector2 tex; 
     } 

     int width = 1000; 
     int height = 1000; 
     const int vertSize = 6 * sizeof(float); 
     RenderForm form; 
     PictureBox pic; 
     SharpDX.Direct3D11.Device dev; 
     DeviceContext dc; 
     SwapChainDescription scd; 
     SwapChain sc; 
     RasterizerStateDescription rsd; 
     RasterizerState rs; 
     Viewport vp; 
     Texture2DDescription depthDesc; 
     DepthStencilView dsv; 
     RenderTargetView rtv; 
     SharpDX.Direct3D11.Buffer buffer; 
     InputLayout il; 
     VertexShader vs; 
     ShaderBytecode vsCode; 
     PixelShader ps; 
     ShaderBytecode psCode; 
     Matrix view; 
     Matrix proj; 
     Matrix mat; 
     Data data; 
     DataStream pointStream; 
     SharpDX.Direct3D11.Buffer pointBuffer; 

     public Test() 
     { 
      init(); 
      initMat(); 

      data.testColor = new Vector4(1.0f, 0.5f, 0.25f, 0.0f); 

      string code = "struct vert { float4 pos : POSITION; float2 tex : TEXCOORD; };\n" 
       + "struct pix { float4 pos : SV_POSITION; float2 tex : TEXCOORD; };\n" 
       + "cbuffer buf1 : register(b0) { float4x4 mat; float4 testColor; }\n" 
       + "pix VS(vert vertIn) { pix pixOut = (pix)0; pixOut.pos = mul(vertIn.pos, mat); pixOut.tex = vertIn.tex; return pixOut; }\n" 
       + "float4 PS(pix pixIn) : SV_Target { return testColor; }"; 

      vsCode = ShaderBytecode.Compile(code, "VS", "vs_5_0"); 
      vs = new VertexShader(dev, vsCode); 
      psCode = ShaderBytecode.Compile(code, "PS", "ps_5_0"); 
      ps = new PixelShader(dev, psCode); 

      dc.VertexShader.Set(vs); 
      dc.PixelShader.Set(ps); 

      il = new InputLayout(dev, ShaderSignature.GetInputSignature(vsCode), 
       new InputElement[] {new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), 
       new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0)}); 

      dc.InputAssembler.InputLayout = il; 
      dc.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; 

      updateBuffer(); 

      RenderLoop.Run(form,() => 
      { 
       dc.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth, 1.0f, 0); 
       dc.ClearRenderTargetView(rtv, Color4.Black); 
       float dist = 10.0f; 
       draw(new Vector3(-dist, -dist, dist), Vector2.Zero, new Vector3(-dist, dist, dist), Vector2.UnitY, 
        new Vector3(dist, dist, dist), Vector2.One); 
      }); 
     } 

     void init() 
     { 
      form = new RenderForm(); 
      form.ClientSize = new System.Drawing.Size(width, height); 
      form.BackColor = System.Drawing.Color.Black; 
      form.FormClosed += form_FormClosed; 
      pic = new PictureBox(); 
      pic.Location = new System.Drawing.Point(0, 0); 
      pic.Size = new Size(width, height); 
      pic.Show(); 
      form.Controls.Add(pic); 

      scd = new SwapChainDescription(); 
      scd.BufferCount = 1; 
      scd.Flags = SwapChainFlags.AllowModeSwitch; 
      scd.IsWindowed = true; 
      scd.ModeDescription = new ModeDescription(width, height, new Rational(60, 1), Format.R8G8B8A8_UNorm); 
      scd.OutputHandle = pic.Handle; 
      scd.SampleDescription = new SampleDescription(1, 0); 
      scd.SwapEffect = SwapEffect.Discard; 
      scd.Usage = Usage.RenderTargetOutput; 

      rsd = new RasterizerStateDescription(); 
      rsd.CullMode = CullMode.None; 
      rsd.DepthBias = 0; 
      rsd.DepthBiasClamp = 0; 
      rsd.FillMode = FillMode.Solid; 
      rsd.IsAntialiasedLineEnabled = true; 
      rsd.IsDepthClipEnabled = true; 
      rsd.IsFrontCounterClockwise = false; 
      rsd.IsMultisampleEnabled = true; 
      rsd.IsScissorEnabled = false; 
      rsd.SlopeScaledDepthBias = 0; 

      SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, scd, out dev, out sc); 
      rs = new RasterizerState(dev, rsd); 
      vp = new Viewport(0, 0, width, height, 0.0f, 1.0f); 
      dc = dev.ImmediateContext; 
      dc.Rasterizer.State = rs; 
      dc.Rasterizer.SetViewports(vp); 

      depthDesc = new Texture2DDescription(); 
      depthDesc.ArraySize = 1; 
      depthDesc.BindFlags = BindFlags.DepthStencil; 
      depthDesc.CpuAccessFlags = CpuAccessFlags.None; 
      depthDesc.Format = Format.D32_Float_S8X24_UInt; 
      depthDesc.Height = height; 
      depthDesc.MipLevels = 1; 
      depthDesc.OptionFlags = ResourceOptionFlags.None; 
      depthDesc.SampleDescription = new SampleDescription(1, 0); 
      depthDesc.Usage = ResourceUsage.Default; 
      depthDesc.Width = width; 

      dsv = new DepthStencilView(dev, new Texture2D(dev, depthDesc)); 
      rtv = new RenderTargetView(dev, (SharpDX.Direct3D11.Resource)SharpDX.Direct3D11.Resource.FromSwapChain<Texture2D>(sc, 0)); 
      dc.OutputMerger.SetTargets(dsv, rtv); 

      buffer = new SharpDX.Direct3D11.Buffer(dev, Marshal.SizeOf(typeof(Data)), 
       ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); 
      dc.VertexShader.SetConstantBuffer(0, buffer); 
     } 

     void initMat() 
     { 
      view = Matrix.LookAtLH(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY); 
      proj = Matrix.PerspectiveFovLH((float)Math.PI/4.0f, (float)width/(float)height, 0.001f, 10000.0f); 
      mat = view * proj; 
      mat.Transpose(); 
      data.mat = mat; 
     } 

     void updateBuffer() 
     { 
      dc.UpdateSubresource<Data>(ref data, buffer); 
     } 

     public void draw(Vector3 p1, Vector2 t1, Vector3 p2, Vector2 t2, Vector3 p3, Vector2 t3) 
     { 
      Vector3[] p = new Vector3[3] {p1, p2, p3}; 
      Vector2[] t = new Vector2[3] {t1, t2, t3}; 
      Point[] points = new Point[3]; 
      for(int i = 0; i < 3; i++) 
      { 
       points[i] = new Point(); 
       points[i].pos = new Vector4(p[i].X, p[i].Y, p[i].Z, 1.0f); 
       points[i].tex = new Vector2(t[i].X, t[i].Y); 
      } 
      using(pointStream = new DataStream(vertSize * 3, true, true)) 
      { 
       pointStream.WriteRange<Point>(points); 
       using(pointBuffer = new SharpDX.Direct3D11.Buffer(dev, pointStream, vertSize * 3, 
        ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)) 
       { 
        dc.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; 
        dc.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(pointBuffer, vertSize, 0)); 
        dc.Draw(3, 0); 
       } 
      } 
     } 

     void form_FormClosed(object sender, FormClosedEventArgs e) 
     { 
      buffer.Dispose(); 
      il.Dispose(); 
      ps.Dispose(); 
      psCode.Dispose(); 
      vs.Dispose(); 
      vsCode.Dispose(); 
      rtv.Dispose(); 
      dsv.Dispose(); 
      dc.ClearState(); 
      dc.Flush(); 
      dc.Dispose(); 
      dev.Dispose(); 
      sc.Dispose(); 
     } 
    } 
} 

而且,這裏是一個更可讀的方式格式化的shader代碼:

struct vert 
{ 
    float4 pos : POSITION; 
    float2 tex : TEXCOORD; 
}; 

struct pix 
{ 
    float4 pos : SV_POSITION; 
    float2 tex : TEXCOORD; 
}; 

cbuffer buf1 : register(b0) 
{ 
    float4x4 mat; 
    float4 testColor; 
} 

pix VS(vert vertIn) 
{ 
    pix pixOut = (pix)0; 
    pixOut.pos = mul(vertIn.pos, mat); 
    pixOut.tex = vertIn.tex; 
    return out; 
} 

float4 PS(pix pixIn) : SV_Target 
{ 
    return testColor; 
} 
+0

使用像http://renderdoc.org/這樣的圖形調試器或集成在VS2013 +中的圖形調試器來調試這個 – xoofx

+0

我會看看我是否可以,但我不知道任何關於它或設置它或任何東西。有人不能只看看代碼有什麼問題嗎?或者更好的是,如果任何人有一個工作源代碼示例指向我,我可以下載或複製文本和使用,將數組數據輸入到常量/紋理緩衝區,這將是非常出色的!理想情況下,我希望在週六之前完成這個任務,否則我將無法在下個週末完成任務,而且我非常焦慮。謝謝。 – MyAccount

+0

另外,糾正我,如果我錯了,但如果我調試,這是在着色器內嗎?所以,它不會告訴我數據在它已經存在的情況下做了什麼,但不告訴我爲什麼當它應該是其他數字時,它們都被初始化爲0?這似乎是C#的一些錯誤。 – MyAccount

回答

0

我不知道這是任何幫助在這裏,但爲什麼去UpdateSubresource在您的updateBuffer()?在SharpDXTutorial/Tutorial16(立方貼圖示例)的緩衝器被初始化與「設備」對象,

device.UpdateData<Data>(dataConstantBuffer, sceneInformation); 

這是一個非常方便的對象。它包含在SharpHelper,SharpDXTutorial的一部分,

https://github.com/RobyDX/SharpDX_Demo/blob/master/SharpDXTutorial/SharpHelper/SharpHelper.csproj

..也許它需要照顧的東西錯過了,更新不斷緩衝?