Im trying to add some more data to my vertex data structure. Im trying to add a vector2 for each instance of a model, but I cant get it to work and was wondering if anyone could give me a nudge in the right direction. The objects render, but the data in textcoord5 is random.
Thanks
The initialize stage, where I create the extra vertex element to pass to the shader
// Create the extra dataVertexElement[] extraElements = new VertexElement[5]; // 4 * vector4 (matrix) + 2 * float (vector2)for (int i = 0; i < extraElements.Length-1; i++){ short matrixOffset = (short)(sizeof(float) * 4 * i); extraElements = new VertexElement(1, matrixOffset, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, (byte)(i+1));}short extraOffset = (short)(sizeof(float) * 4 * 4);extraElements[4] = new VertexElement(2, extraOffset, VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 5);// Put it in thereVertexElement[] oldVertexDeclaration = m_vertexDeclaration.GetVertexElements();VertexElement[] elements = new VertexElement[oldVertexDeclaration.Length + extraElements.Length];oldVertexDeclaration.CopyTo(elements, 0);extraElements.CopyTo(elements, oldVertexDeclaration.Length);// Repalce the vertex declarationm_vertexDeclaration.Dispose();m_vertexDeclaration = new VertexDeclaration(device, elements);
The render stage, currently the data it passes is not very usefull, its only for testing.
public void Draw(GraphicsDevice device, Effect effect, Matrix[] instanceTransforms){ // Temp! Vector2[] otherData = new Vector2[instanceTransforms.Length]; for (int i = 0; i < instanceTransforms.Length; i++) { float t = (float)i / (float)instanceTransforms.Length; otherData = new Vector2(t, 0); } device.VertexDeclaration = m_vertexDeclaration; device.Vertices[0].SetSource(m_vertexBuffer, 0, m_vertexStride); device.Indices = m_indexBuffer; effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); // make sure there is enough space in out buffer to pass the instance data, recalculate it if needed. // not the best way of doing it, but I think it should be fine int matrixDataSize = sizeof(float) * 16 * instanceTransforms.Length; int extraDataSize = sizeof(float) * 2 * otherData.Length; // Matrix data if ((m_instanceMatrixStream == null) || (m_instanceMatrixStream.SizeInBytes < matrixDataSize)) { if (m_instanceMatrixStream != null) m_instanceMatrixStream.Dispose(); m_instanceMatrixStream = new DynamicVertexBuffer(device, matrixDataSize, BufferUsage.WriteOnly); } m_instanceMatrixStream.SetData(instanceTransforms, 0, instanceTransforms.Length, SetDataOptions.Discard); // Extra data if ((m_instanceExtraDataStream == null) || (m_instanceExtraDataStream.SizeInBytes < extraDataSize)) { if (m_instanceExtraDataStream != null) m_instanceExtraDataStream.Dispose(); m_instanceExtraDataStream = new DynamicVertexBuffer(device, extraDataSize, BufferUsage.WriteOnly); } m_instanceExtraDataStream.SetData(otherData, 0, otherData.Length, SetDataOptions.Discard); // Set the current draw process to use the data VertexStreamCollection vertices = device.Vertices; vertices[0].SetFrequencyOfIndexData(instanceTransforms.Length); vertices[1].SetSource(m_instanceMatrixStream, 0, sizeof(float) * 16); vertices[1].SetFrequencyOfInstanceData(1); vertices[2].SetSource(m_instanceExtraDataStream, 0, sizeof(float) * 2); vertices[2].SetFrequencyOfInstanceData(1); // Draw the model device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, m_vertexCount, 0, m_indexCount / 3); // Reset the streams to make sure they are not used later vertices[0].SetSource(null, 0, 0); vertices[1].SetSource(null, 0, 0); vertices[2].SetSource(null, 0, 0); pass.End(); } effect.End();}
The vertex shader
VertexShaderOutput InstancingVertexShader(VertexShaderInput input, float4x4 instanceTransform : TEXCOORD1, float2 extraData : TEXCOORD5){ return VertexShader(input, transpose(instanceTransform), extraData);}