private static OnDiskBufferData BufferDataFromDATA(IKeyValueCollection data) { OnDiskBufferData buffer = new OnDiskBufferData(); buffer.ElementCount = data.GetUInt32Property("m_nElementCount"); buffer.ElementSizeInBytes = data.GetUInt32Property("m_nElementSizeInBytes"); buffer.InputLayoutFields = new List <RenderInputLayoutField>(); var inputLayoutFields = data.GetArray("m_inputLayoutFields"); foreach (var il in inputLayoutFields) { RenderInputLayoutField attrib = new RenderInputLayoutField(); //null-terminated string attrib.SemanticName = System.Text.Encoding.UTF8.GetString(il.GetArray <byte>("m_pSemanticName")).TrimEnd((char)0); attrib.SemanticIndex = il.GetInt32Property("m_nSemanticIndex"); attrib.Format = (DXGI_FORMAT)il.GetUInt32Property("m_Format"); attrib.Offset = il.GetUInt32Property("m_nOffset"); attrib.Slot = il.GetInt32Property("m_nSlot"); attrib.SlotType = (RenderSlotType)il.GetUInt32Property("m_nSlotType"); attrib.InstanceStepRate = il.GetInt32Property("m_nInstanceStepRate"); buffer.InputLayoutFields.Add(attrib); } buffer.Data = data.GetArray <byte>("m_pData"); return(buffer); }
public static float[] ReadVertexAttribute(int offset, OnDiskBufferData vertexBuffer, RenderInputLayoutField attribute) { float[] result; offset = (int)(offset * vertexBuffer.ElementSizeInBytes) + (int)attribute.Offset; // Useful reference: https://github.com/apitrace/dxsdk/blob/master/Include/d3dx_dxgiformatconvert.inl switch (attribute.Format) { case DXGI_FORMAT.R32G32B32_FLOAT: { result = new float[3]; Buffer.BlockCopy(vertexBuffer.Data, offset, result, 0, 12); break; } case DXGI_FORMAT.R32G32B32A32_FLOAT: { result = new float[4]; Buffer.BlockCopy(vertexBuffer.Data, offset, result, 0, 16); break; } case DXGI_FORMAT.R16G16_UNORM: { var shorts = new ushort[2]; Buffer.BlockCopy(vertexBuffer.Data, offset, shorts, 0, 4); result = new[] { shorts[0] / 65535f, shorts[1] / 65535f, }; break; } case DXGI_FORMAT.R16G16_FLOAT: { var shorts = new ushort[2]; Buffer.BlockCopy(vertexBuffer.Data, offset, shorts, 0, 4); result = new[] { HalfTypeHelper.Convert(shorts[0]), HalfTypeHelper.Convert(shorts[1]), }; break; } case DXGI_FORMAT.R32_FLOAT: { result = new float[1]; Buffer.BlockCopy(vertexBuffer.Data, offset, result, 0, 4); break; } case DXGI_FORMAT.R32G32_FLOAT: { result = new float[2]; Buffer.BlockCopy(vertexBuffer.Data, offset, result, 0, 8); break; } case DXGI_FORMAT.R16G16_SINT: { var shorts = new short[2]; Buffer.BlockCopy(vertexBuffer.Data, offset, shorts, 0, 4); result = new float[2]; for (var i = 0; i < 2; i++) { result[i] = shorts[i]; } break; } case DXGI_FORMAT.R16G16B16A16_SINT: { var shorts = new short[4]; Buffer.BlockCopy(vertexBuffer.Data, offset, shorts, 0, 8); result = new float[4]; for (var i = 0; i < 4; i++) { result[i] = shorts[i]; } break; } case DXGI_FORMAT.R8G8B8A8_UINT: case DXGI_FORMAT.R8G8B8A8_UNORM: { var bytes = new byte[4]; Buffer.BlockCopy(vertexBuffer.Data, offset, bytes, 0, 4); result = new float[4]; for (var i = 0; i < 4; i++) { result[i] = attribute.Format == DXGI_FORMAT.R8G8B8A8_UNORM ? bytes[i] / 255f : bytes[i]; } break; } default: throw new NotImplementedException($"Unsupported \"{attribute.SemanticName}\" DXGI_FORMAT.{attribute.Format}"); } return(result); }