I have always used the effects framework to manage my shaders, but I decided to introduce constant buffers, as I'm about to implement geometry instancing and I figured it would give me greater control. And also it was about time I get to know how they work. But I don't think I'm doing it right as my wall sections are just disappearing. So can anyone see what I'm doing wrong ..
So here's all the relevant code :
The CBufferStruct ...
/// <summary>
/// CBufferStruct
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CBufferStruct
{
public Matrix mWorld;
public Matrix mView;
public Matrix mProj;
public static readonly int SizeInBytes = Marshal.SizeOf(typeof(CBufferStruct));
}
Then in the Walls constructor ...
// create cBuffer
BufferDescription bufferDescription = new BufferDescription()
{
BindFlags = BindFlags.ConstantBuffer,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,
SizeInBytes = CBufferStruct.SizeInBytes,
Usage = ResourceUsage.Default,
};
cBuffer = new Buffer(SlimDXGraphics.Device11, bufferDescription);
cBufferStruct = new CBufferStruct()
{
mProj = new Matrix(),
mView = new Matrix(),
mWorld = Matrix.Translation(new Vector3()),
//padding = new Matrix()
};
Then in Walls.RenderToGBuffer() ...
foreach (Chunk chunk in map.VisibleChunks)
{
//if (!(chunk.Coords.X == 1 && chunk.Coords.Y == 1)) // debug code to selectively render a single terrain chunk
foreach (KeyValuePair<int, List<Point>> kVPair in chunk.wallInstanceCollectionsDictionary)
{
foreach (Point p in kVPair.Value)
{
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(map.wall000.VertexBuffer, VertexPCNT.SizeInBytes, 0));
cBufferStruct.mProj = camera.ProjMatrix;
cBufferStruct.mView = camera.ViewMatrix;
cBufferStruct.mWorld = Matrix.Translation(new Vector3(p.X, p.Y, 0));
using (DataStream data = new DataStream(CBufferStruct.SizeInBytes, true, true))
{
data.Position = 0;
data.Write(cBufferStruct);
context.UpdateSubresource(new DataBox(0, 0, data), cBuffer, 0);
data.Dispose();
}
// now bind the constant buffer to the pipeline
context.VertexShader.SetConstantBuffer(cBuffer, 0); // not sure about this, some examples don't have it
// configure vertex shader ------------------------------------------------------------
//effect_Walls.GetVariableByName("gWorld").AsMatrix().SetMatrix(Matrix.Translation(new Vector3(p.X, p.Y, 0)));
//effect_Walls.GetVariableByName("gView").AsMatrix().SetMatrix(camera.ViewMatrix);
//effect_Walls.GetVariableByName("gProj").AsMatrix().SetMatrix(camera.ProjMatrix);
effect_Walls.GetVariableByName("gTexture").AsResource().SetResource(map.SRVWallTexture);
// draw -------------------------------------------------------------------------------
for (int pass = 0; pass < effectTech_Walls.Description.PassCount; ++pass)
{
EffectPass Pass = effectTech_Walls.GetPassByIndex(pass);
System.Diagnostics.Debug.Assert(Pass.IsValid, "Invalid EffectPass");
Pass.Apply(context);
if (map.wall000.IndexCount == 0)
context.Draw(map.wall000.VertexCount, 0);
else
context.DrawIndexed(map.wall000.IndexCount, 0, 0);
};
}
}
}
Edit : And here's the shader vars ...
// constant buffers need to be a multiple of 16 byte in size
cbuffer gConstantBuffer : register (b0)
{
// spacial transforms
float4x4 gWorld;
float4x4 gView;
float4x4 gProj;
// padding
//float4x4 padding;
}
Texture2D<float4> gTexture : register (t0);
Thanks for any help or comments.