#if UNITY_EDITOR || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
#define UNITY_PLATFORM_SUPPORTS_LINEAR
#elif UNITY_IOS || UNITY_ANDROID
#if UNITY_5_5_OR_NEWER || (UNITY_5 && !UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2 && !UNITY_5_3 && !UNITY_5_4)
#define UNITY_PLATFORM_SUPPORTS_LINEAR
#endif
#endif
#if UNITY_5_4_OR_NEWER || (UNITY_5 && !UNITY_5_0)
#define UNITY_HELPATTRIB
#endif
using UnityEngine;
//-----------------------------------------------------------------------------
// Copyright 2015-2018 RenderHeads Ltd. All rights reserverd.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo
{
///
/// Displays the video from MediaPlayer component using IMGUI
///
[AddComponentMenu("AVPro Video/Display IMGUI", 200)]
#if UNITY_HELPATTRIB
[HelpURL("http://renderheads.com/product/avpro-video/")]
#endif
[ExecuteInEditMode]
public class DisplayIMGUI : MonoBehaviour
{
private const string PropChromaTexName = "_ChromaTex";
public MediaPlayer _mediaPlayer;
public bool _displayInEditor = true;
public ScaleMode _scaleMode = ScaleMode.ScaleToFit;
public Color _color = Color.white;
public bool _alphaBlend = false;
[SerializeField]
private bool _useDepth = false;
public int _depth = 0;
public bool _fullScreen = true;
[Range(0f, 1f)]
public float _x = 0.0f;
[Range(0f, 1f)]
public float _y = 0.0f;
[Range(0f, 1f)]
public float _width = 1.0f;
[Range(0f, 1f)]
public float _height = 1.0f;
private static int _propAlphaPack;
private static int _propVertScale;
private static int _propApplyGamma;
private static int _propChromaTex;
private static Shader _shaderAlphaPacking;
private Material _material;
void Awake()
{
if (_propAlphaPack == 0)
{
_propAlphaPack = Shader.PropertyToID("AlphaPack");
_propVertScale = Shader.PropertyToID("_VertScale");
_propApplyGamma = Shader.PropertyToID("_ApplyGamma");
_propChromaTex = Shader.PropertyToID(PropChromaTexName);
}
}
void Start()
{
// Disabling this lets you skip the GUI layout phase which helps performance, but this also breaks the GUI.depth usage.
if (!_useDepth)
{
this.useGUILayout = false;
}
if (_shaderAlphaPacking == null)
{
_shaderAlphaPacking = Shader.Find("AVProVideo/IMGUI/Texture Transparent");
if (_shaderAlphaPacking == null)
{
Debug.LogWarning("[AVProVideo] Missing shader AVProVideo/IMGUI/Transparent Packed");
}
}
}
void OnDestroy()
{
// Destroy existing material
if (_material != null)
{
#if UNITY_EDITOR
Material.DestroyImmediate(_material);
#else
Material.Destroy(_material);
#endif
_material = null;
}
}
private Shader GetRequiredShader()
{
Shader result = null;
switch (_mediaPlayer.m_AlphaPacking)
{
case AlphaPacking.None:
break;
case AlphaPacking.LeftRight:
case AlphaPacking.TopBottom:
result = _shaderAlphaPacking;
break;
}
#if UNITY_PLATFORM_SUPPORTS_LINEAR
if (result == null && _mediaPlayer.Info != null)
{
// If the player does support generating sRGB textures then we need to use a shader to convert them for display via IMGUI
if (QualitySettings.activeColorSpace == ColorSpace.Linear && _mediaPlayer.Info.PlayerSupportsLinearColorSpace())
{
result = _shaderAlphaPacking;
}
}
#endif
if (result == null && _mediaPlayer.TextureProducer != null)
{
if (_mediaPlayer.TextureProducer.GetTextureCount() == 2)
{
result = _shaderAlphaPacking;
}
}
return result;
}
void Update()
{
if (_mediaPlayer != null)
{
// Get required shader
Shader currentShader = null;
if (_material != null)
{
currentShader = _material.shader;
}
Shader nextShader = GetRequiredShader();
// If the shader requirement has changed
if (currentShader != nextShader)
{
// Destroy existing material
if (_material != null)
{
#if UNITY_EDITOR
Material.DestroyImmediate(_material);
#else
Material.Destroy(_material);
#endif
_material = null;
}
// Create new material
if (nextShader != null)
{
_material = new Material(nextShader);
}
}
// Apply material changes
if (_material != null)
{
if (_material.HasProperty(_propAlphaPack))
{
Helper.SetupAlphaPackedMaterial(_material, _mediaPlayer.m_AlphaPacking);
}
#if UNITY_PLATFORM_SUPPORTS_LINEAR
// Apply gamma
if (_material.HasProperty(_propApplyGamma) && _mediaPlayer.Info != null)
{
Helper.SetupGammaMaterial(_material, !_mediaPlayer.Info.PlayerSupportsLinearColorSpace());
}
#else
_propApplyGamma |= 0;
#endif
}
}
}
void OnGUI()
{
#if UNITY_EDITOR
if (!Application.isPlaying && _displayInEditor)
{
GUI.depth = _depth;
GUI.color = _color;
Rect rect = GetRect();
Texture2D icon = Resources.Load("AVProVideoIcon");
Rect uv = rect;
uv.x /= Screen.width;
uv.width /= Screen.width;
uv.y /= Screen.height;
uv.height /= Screen.height;
uv.width *= 16f;
uv.height *= 16f;
uv.x += 0.5f;
uv.y += 0.5f;
GUI.DrawTextureWithTexCoords(rect, icon, uv);
return;
}
#endif
if (_mediaPlayer == null)
{
return;
}
bool requiresVerticalFlip = false;
Texture texture = null;
if (_displayInEditor)
{
#if UNITY_EDITOR
texture = Texture2D.whiteTexture;
#endif
}
if (_mediaPlayer.Info != null && !_mediaPlayer.Info.HasVideo())
{
texture = null;
}
if (_mediaPlayer.TextureProducer != null)
{
if ((_mediaPlayer.m_Resample ? _mediaPlayer.FrameResampler.OutputTexture[0] : _mediaPlayer.TextureProducer.GetTexture()) != null)
{
texture = _mediaPlayer.m_Resample ? _mediaPlayer.FrameResampler.OutputTexture[0] : _mediaPlayer.TextureProducer.GetTexture();
requiresVerticalFlip = _mediaPlayer.TextureProducer.RequiresVerticalFlip();
}
if (_mediaPlayer.TextureProducer.GetTextureCount() == 2 && _material != null)
{
Texture resamplerTex = _mediaPlayer.FrameResampler == null || _mediaPlayer.FrameResampler.OutputTexture == null ? null : _mediaPlayer.FrameResampler.OutputTexture[1];
Texture chroma = _mediaPlayer.m_Resample ? resamplerTex : _mediaPlayer.TextureProducer.GetTexture(1);
_material.SetTexture(_propChromaTex, chroma);
_material.EnableKeyword("USE_YPCBCR");
}
}
if (texture != null)
{
if (!_alphaBlend || _color.a > 0f)
{
GUI.depth = _depth;
GUI.color = _color;
Rect rect = GetRect();
if (_material != null)
{
if (requiresVerticalFlip)
{
_material.SetFloat(_propVertScale, -1f);
}
else
{
_material.SetFloat(_propVertScale, 1f);
}
Helper.DrawTexture(rect, texture, _scaleMode, _mediaPlayer.m_AlphaPacking, _material);
}
else
{
if (requiresVerticalFlip)
{
GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0f, rect.y + (rect.height / 2f)));
}
GUI.DrawTexture(rect, texture, _scaleMode, _alphaBlend);
}
}
}
}
public Rect GetRect()
{
Rect rect;
if (_fullScreen)
{
rect = new Rect(0.0f, 0.0f, Screen.width, Screen.height);
}
else
{
rect = new Rect(_x * (Screen.width - 1), _y * (Screen.height - 1), _width * Screen.width, _height * Screen.height);
}
return rect;
}
}
}