Hi
This is my first post on this site. I used to be at App Hub but I resently started working directly to DirectX and the DirectX activity there is close to none thats why I joined here so that I might have someone to talk to. But enoght about that and on to my question.
For a few days I have tried to get hardware instancing to work but with no luck. I have googled a lot and read everything on the topic that I can find. Everything compiles and It draws one of the instances where only one of the vertrices are affected by the world coordinate. I'm at the point where I want to throw the computer out the window so please have a look at this and help me if you can!
Here is the instancing parts of my code.
private int _instanceCount;
private InstanceFormat[] _instances;
private VertexBuffer _instanceBuffer;
private int _vertexCount;
private VertexFormat[] _vertices;
private VertexBuffer _vertexBuffer;
private int _indexCount;
private uint[] _indices;
private IndexBuffer _indexBuffer;
private D3D.Effect _instancingEffect;
private VertexDeclaration _vertexDeclaration;
int vertexSize;
int instanceSize;
struct VertexFormat
{
public Vector3 Position;
public Vector2 Texture;
public VertexFormat(Vector3 position, Vector2 texture)
{
Position = position;
Texture = texture;
}
}
struct InstanceFormat
{
public Vector3 World;
public InstanceFormat(Vector3 world)
{
World = world;
}
}
This is where I create my Declaration and fill the buffers:
#region Set up vertex declaration
vertexSize = 20;
instanceSize = 12;
VertexElement[] vertexElementsArray = new VertexElement[]
{
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
new VertexElement(1, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 1),
VertexElement.VertexDeclarationEnd
};
// Create a vertex declaration based on the vertex elements.
_vertexDeclaration = new VertexDeclaration(_device, vertexElementsArray);
#endregion
#region Set up vertex buffer for vertices
_vertexCount = 4;
_vertexBuffer = new VertexBuffer(_device, vertexSize*_vertexCount, Usage.Dynamic | Usage.WriteOnly, VertexFormats.Position | VertexFormats.Texture0, Pool.Default);
_vertices = new VertexFormat[_vertexCount];
_vertices[0] = new VertexFormat(new Vector3(0, 0, 0), new Vector2(0, 0));
_vertices[1] = new VertexFormat(new Vector3(0, 1, 0), new Vector2(0, 1));
_vertices[2] = new VertexFormat(new Vector3(1, 0, 0), new Vector2(1, 0));
_vertices[3] = new VertexFormat(new Vector3(1, 1, 0), new Vector2(1, 1));
_vertexBuffer.SetData(_vertices, 0, LockFlags.None);
#endregion
#region Set up index buffer
_indexCount = 6;
_indexBuffer = new IndexBuffer(_device, sizeof(uint)*_indexCount, Usage.WriteOnly, Pool.Default, false);
_indices = new uint[_indexCount];
_indices[0] = 0; _indices[1] = 1; _indices[2] = 2;
_indices[3] = 1; _indices[4] = 3; _indices[5] = 2;
_indexBuffer.SetData(_indices, 0, LockFlags.None);
#endregion
#region Set up vertex buffer for instances
_instanceCount = 10;
_instanceBuffer = new VertexBuffer(_device, instanceSize * _instanceCount, Usage.Dynamic | Usage.WriteOnly, VertexFormats.None, Pool.Default);
_instances = new InstanceFormat[_instanceCount];
for (int i = 0; i < _instanceCount; i++)
_instances = new InstanceFormat(new Vector3(i, 0, i));
_instanceBuffer.SetData(_instances, 0, LockFlags.None);
#endregion
And this is my draw method:
_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0);
_device.BeginScene();
_device.VertexDeclaration = _vertexDeclaration;
_device.Indices = _indexBuffer;
_device.SetStreamSource(0, _vertexBuffer, 0, vertexSize);
_device.SetStreamSource(1, _instanceBuffer, 0, instanceSize);
// Specify how many times the vertex stream source and the instance stream source should be rendered.
_device.SetStreamSourceFrequency(0, _instanceCount);
_device.SetStreamSourceFrequency(1, 1);
_instancingEffect.Technique = "Instancing";
_instancingEffect.SetValue("WVP", _camera.view * _camera.projection);
_instancingEffect.SetValue("cubeTexture", _textures[1]);
int numpasses = _instancingEffect.Begin(0);
for (int i = 0; i < numpasses; i++)
{
_instancingEffect.BeginPass(i);
_device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertexCount, 0, _indexCount / 3);
_instancingEffect.EndPass();
}
_instancingEffect.End();
_device.SetStreamSourceFrequency(0, 1);
_device.SetStreamSourceFrequency(1, 1);
_device.EndScene();
_device.Present();
And here is my shader:
float4x4 WVP;
texture cubeTexture;
sampler TextureSampler = sampler_state
{
texture = <cubeTexture>;
mipfilter = LINEAR;
minfilter = LINEAR;
magfilter = LINEAR;
};
struct InstancingVSinput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float4 World : TEXCOORD1;
};
struct InstancingVSoutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
InstancingVSoutput InstancingVS(InstancingVSinput input)
{
InstancingVSoutput output;
// Transform the vertex into world coordinates.
float4 pos = input.Position + input.World;
// Transform the vertex from world coordinates into screen coordinates.
output.Position = mul(pos, WVP);
output.TexCoord = input.TexCoord;
return output;
}
float4 InstancingPS(InstancingVSoutput input) : COLOR0
{
return float4(1,1,1,1);// tex2D(TextureSampler, input.TexCoord);
}
technique Instancing
{
pass Pass0
{
VertexShader = compile vs_3_0 InstancingVS();
PixelShader = compile ps_3_0 InstancingPS();
}
}
Edit: I should probably mention that I have a Radeon HD 5770.