我正在尝试访问统一参数并在 SharpDx 中更改它的值。我已经在 SharpDx 板上发布了这个,但我没有得到回复,所以我在这里试试运气。通过谷歌我找到了这个例子http://timjones.tw/blog/archive/2011/03/08/marshalling-c-structures-into-directd--cbuffers-using但是DataBox的结构在最新的SharpDx版本中发生了变化. 现在它的 (intPr, int,int) 不像链接中使用的那样
var dataBox = new DataBox(0, 0, _dataStream);
这是我尝试过的 namespace MiniTri { /// /// SharpDX-MiniTri Direct3D 11 Sample 的 SharpDX 端口 /// ///
[StructLayout(LayoutKind.Sequential)]
struct Variables
{
public float R, G, B, A;
}
internal static class Program
{
[STAThread]
private static unsafe void Main()
{
var form = new RenderForm("SharpDX - MiniTri Direct3D 11 Sample TEST");
// SwapChain description
var desc = new SwapChainDescription()
{
BufferCount = 1,
ModeDescription =
new ModeDescription(form.ClientSize.Width, form.ClientSize.Height,
new Rational(60, 1), Format.R8G8B8A8_UNorm),
IsWindowed = true,
OutputHandle = form.Handle,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
// Create Device and SwapChain
Device device;
SwapChain swapChain;
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain);
var context = device.ImmediateContext;
// Ignore all windows events
var factory = swapChain.GetParent<Factory>();
factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);
// New RenderTargetView from the backbuffer
var backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain, 0);
var renderView = new RenderTargetView(device, backBuffer);
// Compile Vertex and Pixel shaders
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None);
var vertexShader = new VertexShader(device, vertexShaderByteCode);
var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None);
var pixelShader = new PixelShader(device, pixelShaderByteCode);
//Layout Color
// Layout from VertexShader input signature
var layout = new InputLayout(
device,
ShaderSignature.GetInputSignature(vertexShaderByteCode),
new[]
{
new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 0, 1)
});
// Instantiate Vertex buiffer from vertex data
var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[]
{
new Vector3(-0.9f, -0.2f, 0.0f),
new Vector3(0.0f, 0.5f, 0.5f),
new Vector3(0.5f, -0.5f, 0.5f),
new Vector3(-0.5f, -0.5f, 0.5f)
});
// Instantiate Vertex buiffer from vertex data
var verticesColors = Buffer.Create(device, BindFlags.VertexBuffer, new[]
{
new Vector4(1.0f, 1.0f, 1.0f, 1.0f),
new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
});
var triangles = Buffer.Create(device, BindFlags.IndexBuffer, new short[]
{
1,
2,
3
});
// Prepare All the stages
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding[]
{
new VertexBufferBinding(vertices,12, 0),
new VertexBufferBinding(verticesColors,16, 0)
}
);
context.InputAssembler.SetIndexBuffer(triangles, Format.R16_UInt, 0);
context.VertexShader.Set(vertexShader);
context.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f));
context.PixelShader.Set(pixelShader);
context.OutputMerger.SetTargets(renderView);
//In HLSL global variables are considered uniform by default.
//It's also settled that a variable coming out of the vertex shader stage for example is varying (HLSL doesn't need this keyword at all!).
//Note that GLSL keywords uniform/varying are inherited from RSL (RenderMan shading language).
//Uniform Parameter
// UniformHandle testFarbeHandle = pixelShader.GetUniformParam("TestFarbe");
// pixelShader.SetUniform(testFarbeHandle, Handle.Color.Black);
//Effect handle = new Effect(device, pixelShaderByteCode, EffectFlags.None);
//handle.GetVariableByName("TestFarbe").AsVector().Set(Color.Red);
var getUniform = new Buffer(device, new BufferDescription
{
Usage = ResourceUsage.Default,
SizeInBytes = sizeof(Variables),
BindFlags = BindFlags.ConstantBuffer
});
var cb = new Variables();
cb.R = 1.0f;
cb.G = 0.0f;
cb.B = 0.0f;
cb.A = 1.0f;
var data = new DataStream(sizeof(Variables), true, true);
data.Write(cb);
data.Position = 0;
context.UpdateSubresource(new DataBox(data.PositionPointer, 0, 0), getUniform, 0);
context.VertexShader.SetConstantBuffer(0, getUniform);
// Main loop
RenderLoop.Run(form, () =>
{
context.ClearRenderTargetView(renderView, Color.Black);
context.DrawIndexed(3, 0, 0);
swapChain.Present(0, PresentFlags.None);
});
// Release all resources
vertexShaderByteCode.Dispose();
vertexShader.Dispose();
pixelShaderByteCode.Dispose();
pixelShader.Dispose();
vertices.Dispose();
layout.Dispose();
renderView.Dispose();
backBuffer.Dispose();
context.ClearState();
context.Flush();
device.Dispose();
context.Dispose();
swapChain.Dispose();
factory.Dispose();
}
}
}
但正如我所说,自从 DataBox 改变了这条线
context.UpdateSubresource(new DataBox(data, 0, 0), getUniform, 0);
.Fx 文件如下所示
cbuffer Variables : register(b0){
float4 TestFarbe;
}
struct VS_IN
{
float4 pos : POSITION;
float4 col : COLOR;
};
struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};
PS_IN VS( VS_IN input )
{
PS_IN output = (PS_IN)0;
output.pos = input.pos;
output.col = input.col;
return output;
}
float4 PS( PS_IN input ) : SV_Target
{
return TestFarbe;
}
我得到的只是一个黑屏。有任何想法吗?