- Refactored the metro FormatConverter - Refactored and fixed the metro index and vertex buffer - Implemented setting multiple texture parameters under metro
171 lines
5.1 KiB
C#
171 lines
5.1 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Dx11 = SharpDX.Direct3D11;
|
|
|
|
// This file is part of the ANX.Framework created by the
|
|
// "ANX.Framework developer group" and released under the Ms-PL license.
|
|
// For details see: http://anxframework.codeplex.com/license
|
|
|
|
namespace ANX.RenderSystem.Windows.Metro.Shader
|
|
{
|
|
public class ParameterBuffer : IDisposable
|
|
{
|
|
#region Private
|
|
private Dx11.Buffer nativeBuffer;
|
|
private NativeDxDevice graphicsDevice;
|
|
private Effect_Metro parentEffect;
|
|
|
|
private int[] parameterOffsets;
|
|
private byte[] setData;
|
|
private int dataSize;
|
|
#endregion
|
|
|
|
#region Constructor
|
|
public ParameterBuffer(Effect_Metro setParentEffect,
|
|
NativeDxDevice setGraphicsDevice)
|
|
{
|
|
graphicsDevice = setGraphicsDevice;
|
|
parentEffect = setParentEffect;
|
|
dataSize = 0;
|
|
|
|
var offsets = new System.Collections.Generic.List<int>();
|
|
foreach(var parameter in parentEffect.shader.Parameters)
|
|
{
|
|
if (parameter.IsTexture == false)
|
|
{
|
|
offsets.Add(dataSize);
|
|
dataSize += parameter.SizeInBytes;
|
|
}
|
|
}
|
|
|
|
parameterOffsets = offsets.ToArray();
|
|
setData = new byte[dataSize];
|
|
|
|
nativeBuffer = new Dx11.Buffer(graphicsDevice.NativeDevice, dataSize,
|
|
Dx11.ResourceUsage.Default, Dx11.BindFlags.ConstantBuffer,
|
|
Dx11.CpuAccessFlags.None, Dx11.ResourceOptionFlags.None, 0);
|
|
}
|
|
#endregion
|
|
|
|
#region SetParameter (T)
|
|
public void SetParameter<T>(string parameterName, ref T value) where T : struct
|
|
{
|
|
int indexOfParameter = FindParameterIndex(parameterName);
|
|
if (indexOfParameter == -1)
|
|
return;
|
|
|
|
int size = Marshal.SizeOf(typeof(T));
|
|
byte[] dataToAdd = new byte[size];
|
|
IntPtr ptr = Marshal.AllocHGlobal(size);
|
|
|
|
Marshal.StructureToPtr(value, ptr, true);
|
|
Marshal.Copy(ptr, setData, parameterOffsets[indexOfParameter], size);
|
|
Marshal.FreeHGlobal(ptr);
|
|
}
|
|
#endregion
|
|
|
|
#region SetParameter (T[])
|
|
public void SetParameter<T>(string parameterName, T[] value) where T : struct
|
|
{
|
|
int indexOfParameter = FindParameterIndex(parameterName);
|
|
if (indexOfParameter == -1)
|
|
return;
|
|
|
|
int sizePerItem = Marshal.SizeOf(typeof(T));
|
|
int offset = 0;
|
|
IntPtr ptr = Marshal.AllocHGlobal(sizePerItem);
|
|
for (int index = 0; index < value.Length; index++)
|
|
{
|
|
Marshal.StructureToPtr(value[index], ptr, true);
|
|
Marshal.Copy(ptr, setData, parameterOffsets[indexOfParameter] + offset, sizePerItem);
|
|
offset += sizePerItem;
|
|
}
|
|
Marshal.FreeHGlobal(ptr);
|
|
}
|
|
#endregion
|
|
|
|
#region SetParameter (float[])
|
|
public void SetParameter(string parameterName, float[] value)
|
|
{
|
|
int indexOfParameter = FindParameterIndex(parameterName);
|
|
if (indexOfParameter == -1)
|
|
return;
|
|
|
|
byte[] result = UnionArraySerializer.Unify(value);
|
|
Array.Copy(result, 0, setData, parameterOffsets[indexOfParameter], result.Length);
|
|
}
|
|
#endregion
|
|
|
|
#region SetParameter (int[])
|
|
public void SetParameter(string parameterName, int[] value)
|
|
{
|
|
int indexOfParameter = FindParameterIndex(parameterName);
|
|
if (indexOfParameter == -1)
|
|
return;
|
|
|
|
byte[] result = UnionArraySerializer.Unify(value);
|
|
Array.Copy(result, 0, setData, parameterOffsets[indexOfParameter], result.Length);
|
|
}
|
|
#endregion
|
|
|
|
#region SetParameter (byte[])
|
|
public void SetParameter(string parameterName, byte[] value)
|
|
{
|
|
int indexOfParameter = FindParameterIndex(parameterName);
|
|
if (indexOfParameter == -1)
|
|
return;
|
|
|
|
Array.Copy(value, 0, setData, parameterOffsets[indexOfParameter], value.Length);
|
|
}
|
|
#endregion
|
|
|
|
#region FindParameterIndex
|
|
private int FindParameterIndex(string parameterName)
|
|
{
|
|
int searchIndex = 0;
|
|
foreach (var parameter in parentEffect.shader.Parameters)
|
|
{
|
|
if (parameter.Name == parameterName)
|
|
return searchIndex;
|
|
|
|
searchIndex++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
#endregion
|
|
|
|
#region Apply
|
|
public void Apply()
|
|
{
|
|
graphicsDevice.NativeContext.VertexShader.SetConstantBuffer(0, nativeBuffer);
|
|
|
|
IntPtr dataPtr;
|
|
unsafe
|
|
{
|
|
fixed (byte* ptr = &setData[0])
|
|
dataPtr = (IntPtr)ptr;
|
|
}
|
|
|
|
// Reset really needed? evaluate
|
|
setData = new byte[dataSize];
|
|
var dataBox = new SharpDX.DataBox(dataPtr);
|
|
graphicsDevice.NativeContext.UpdateSubresource(dataBox, nativeBuffer);
|
|
}
|
|
#endregion
|
|
|
|
#region Dispose
|
|
public void Dispose()
|
|
{
|
|
if (nativeBuffer != null)
|
|
{
|
|
nativeBuffer.Dispose();
|
|
nativeBuffer = null;
|
|
}
|
|
|
|
graphicsDevice = null;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|