2016-02-03 103 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

..也许它需要照顾的东西错过了,更新不断缓冲?