// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.UI
{
// Basic value types within a shader
public enum ShaderPropertyType { Color, Float, Range, TexEnv, Vector, None }
///
/// Obsolete container. Only exists to support backward compatibility to copy values from old scriptableobjects
///
[System.Serializable]
public struct ShaderProperties
{
public string Name;
public ShaderPropertyType Type;
public Vector2 Range;
}
///
/// Collection of shader and material utilities
///
public static class InteractableThemeShaderUtils
{
///
/// Get a MaterialPropertyBlock and copy the designated properties
///
public static MaterialPropertyBlock InitMaterialPropertyBlock(GameObject gameObject, List props)
{
MaterialPropertyBlock materialBlock = GetPropertyBlock(gameObject);
Renderer renderer = gameObject.GetComponent();
if (renderer != null)
{
Material material = GetValidMaterial(renderer);
if (material != null)
{
foreach (ThemeStateProperty prop in props)
{
switch (prop.Type)
{
case ThemePropertyTypes.Color:
Color color = material.GetVector(prop.ShaderPropertyName);
materialBlock.SetColor(prop.ShaderPropertyName, color);
break;
case ThemePropertyTypes.Texture:
Texture tex = material.GetTexture(prop.ShaderPropertyName);
if (tex != null)
{
materialBlock.SetTexture(prop.ShaderPropertyName, tex);
}
break;
case ThemePropertyTypes.ShaderFloat:
case ThemePropertyTypes.ShaderRange:
float value = material.GetFloat(prop.ShaderPropertyName);
materialBlock.SetFloat(prop.ShaderPropertyName, value);
break;
default:
break;
}
}
}
gameObject.GetComponent().SetPropertyBlock(materialBlock);
}
return materialBlock;
}
///
/// Get the MaterialPropertyBlock from a renderer on a gameObject
///
public static MaterialPropertyBlock GetPropertyBlock(GameObject gameObject)
{
MaterialPropertyBlock materialBlock = new MaterialPropertyBlock();
Renderer renderer = gameObject.GetComponent();
if (renderer != null)
{
renderer.GetPropertyBlock(materialBlock);
}
return materialBlock;
}
///
/// Grab the shared material to avoid creating new material instances and breaking batching.
/// Because MaterialPropertyBlocks are used for setting material properties the shared material is
/// used to set the initial state of the MaterialPropertyBlock(s) before mutating state.
///
public static Material GetValidMaterial(Renderer renderer)
{
Material material = null;
if (renderer != null)
{
material = renderer.sharedMaterial;
}
return material;
}
}
}