Skip to content

Instantly share code, notes, and snippets.

@ilexp
Created September 25, 2017 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilexp/5b999ddbe49016b9a96d57b6f991154d to your computer and use it in GitHub Desktop.
Save ilexp/5b999ddbe49016b9a96d57b6f991154d to your computer and use it in GitHub Desktop.
ShaderParameters WiP
using System;
using System.Collections.Generic;
using System.Linq;
using Duality.Editor;
using Duality.Resources;
namespace Duality.Drawing
{
public class ShaderParameters
{
private Dictionary<string,ContentRef<Texture>> textures = null;
private Dictionary<string,float[]> uniforms = null;
public void Set<T>(string name, params T[] value) where T : struct
{
if (string.IsNullOrEmpty(name)) throw new ArgumentException("The parameter name cannot be null or empty.", "name");
if (value == null) throw new ArgumentNullException("value");
if (value.Length == 0) throw new ArgumentException("At least one parameter value needs to be specified.", "value");
float[] rawData;
if (typeof(T) == typeof(float))
{
this.EnsureUniformData(name, value.Length * 1, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i] = ((float)(object)value[i]);
}
}
else if (typeof(T) == typeof(Vector2))
{
this.EnsureUniformData(name, value.Length * 2, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i * 2 + 0] = ((Vector2)(object)value[i]).X;
rawData[i * 2 + 1] = ((Vector2)(object)value[i]).Y;
}
}
else if (typeof(T) == typeof(Vector3))
{
this.EnsureUniformData(name, value.Length * 3, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i * 3 + 0] = ((Vector3)(object)value[i]).X;
rawData[i * 3 + 1] = ((Vector3)(object)value[i]).Y;
rawData[i * 3 + 2] = ((Vector3)(object)value[i]).Z;
}
}
else if (typeof(T) == typeof(Vector4))
{
this.EnsureUniformData(name, value.Length * 4, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i * 4 + 0] = ((Vector4)(object)value[i]).X;
rawData[i * 4 + 1] = ((Vector4)(object)value[i]).Y;
rawData[i * 4 + 2] = ((Vector4)(object)value[i]).Z;
rawData[i * 4 + 3] = ((Vector4)(object)value[i]).W;
}
}
else if (typeof(T) == typeof(Matrix3))
{
this.EnsureUniformData(name, value.Length * 9, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i * 9 + 0] = ((Matrix3)(object)value[i]).Row0.X;
rawData[i * 9 + 1] = ((Matrix3)(object)value[i]).Row0.Y;
rawData[i * 9 + 2] = ((Matrix3)(object)value[i]).Row0.Z;
rawData[i * 9 + 3] = ((Matrix3)(object)value[i]).Row1.X;
rawData[i * 9 + 4] = ((Matrix3)(object)value[i]).Row1.Y;
rawData[i * 9 + 5] = ((Matrix3)(object)value[i]).Row1.Z;
rawData[i * 9 + 6] = ((Matrix3)(object)value[i]).Row2.X;
rawData[i * 9 + 7] = ((Matrix3)(object)value[i]).Row2.Y;
rawData[i * 9 + 8] = ((Matrix3)(object)value[i]).Row2.Z;
}
}
else if (typeof(T) == typeof(Matrix4))
{
this.EnsureUniformData(name, value.Length * 16, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i * 16 + 0] = ((Matrix4)(object)value[i]).Row0.X;
rawData[i * 16 + 1] = ((Matrix4)(object)value[i]).Row0.Y;
rawData[i * 16 + 2] = ((Matrix4)(object)value[i]).Row0.Z;
rawData[i * 16 + 3] = ((Matrix4)(object)value[i]).Row0.W;
rawData[i * 16 + 4] = ((Matrix4)(object)value[i]).Row1.X;
rawData[i * 16 + 5] = ((Matrix4)(object)value[i]).Row1.Y;
rawData[i * 16 + 6] = ((Matrix4)(object)value[i]).Row1.Z;
rawData[i * 16 + 7] = ((Matrix4)(object)value[i]).Row1.W;
rawData[i * 16 + 8] = ((Matrix4)(object)value[i]).Row2.X;
rawData[i * 16 + 9] = ((Matrix4)(object)value[i]).Row2.Y;
rawData[i * 16 + 10] = ((Matrix4)(object)value[i]).Row2.Z;
rawData[i * 16 + 11] = ((Matrix4)(object)value[i]).Row2.W;
rawData[i * 16 + 12] = ((Matrix4)(object)value[i]).Row3.X;
rawData[i * 16 + 13] = ((Matrix4)(object)value[i]).Row3.Y;
rawData[i * 16 + 14] = ((Matrix4)(object)value[i]).Row3.Z;
rawData[i * 16 + 15] = ((Matrix4)(object)value[i]).Row3.W;
}
}
else if (typeof(T) == typeof(int))
{
this.EnsureUniformData(name, value.Length * 1, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i] = ((int)(object)value[i]);
}
}
else if (typeof(T) == typeof(Point2))
{
this.EnsureUniformData(name, value.Length * 2, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i * 2 + 0] = ((Point2)(object)value[i]).X;
rawData[i * 2 + 1] = ((Point2)(object)value[i]).Y;
}
}
else if (typeof(T) == typeof(bool))
{
this.EnsureUniformData(name, value.Length * 1, out rawData);
for (int i = 0; i < value.Length; i++)
{
rawData[i] = ((bool)(object)value[i]) ? 1.0f : 0.0f;
}
}
else if (typeof(T) == typeof(ContentRef<Texture>))
{
if (value.Length > 1) throw new ArgumentException("Can't assign more than one texture to a single shader parameter.", "value");
this.textures[name] = (ContentRef<Texture>)(object)value[0];
}
else
{
throw new NotSupportedException("Setting shader parameters to values of this type is not supported.");
}
}
public void Get<T>(string name, T[] target) where T : struct
{
if (string.IsNullOrEmpty(name)) throw new ArgumentException("The parameter name cannot be null or empty.", "name");
if (target == null) throw new ArgumentNullException("target");
if (target.Length == 0) throw new ArgumentException("At least one parameter target needs to be available.", "target");
// ToDo
}
private void EnsureUniformData(string name, int size, out float[] data)
{
if (!this.uniforms.TryGetValue(name, out data) || data.Length != size)
{
data = new float[size];
this.uniforms[name] = data;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment