123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- #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-2020 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProVideo
- {
- /// <summary>
- /// Sets up a mesh to display the video from a MediaPlayer
- /// </summary>
- [AddComponentMenu("AVPro Video/Apply To Mesh", 300)]
- #if UNITY_HELPATTRIB
- [HelpURL("http://renderheads.com/products/avpro-video/")]
- #endif
- public class ApplyToMesh : MonoBehaviour
- {
- // TODO: add specific material / material index to target in the mesh if there are multiple materials
- [Header("Media Source")]
- [SerializeField] public MediaPlayer _media = null;
- public MediaPlayer Player
- {
- get { return _media; }
- set { ChangeMediaPlayer(value); }
- }
- [Tooltip("Default texture to display when the video texture is preparing")]
- [SerializeField] public Texture2D _defaultTexture = null;
- public Texture2D DefaultTexture
- {
- get { return _defaultTexture; }
- set { if (_defaultTexture != value) { _defaultTexture = value; _isDirty = true; } }
- }
- [Space(8f)]
- [Header("Renderer Target")]
- [SerializeField] public Renderer _mesh = null;
- public Renderer MeshRenderer
- {
- get { return _mesh; }
- set { if (_mesh != value) { _mesh = value; _isDirty = true; } }
- }
- [SerializeField] string _texturePropertyName = "_MainTex";
- public string TexturePropertyName
- {
- get { return _texturePropertyName; }
- set
- {
- if (_texturePropertyName != value)
- {
- _texturePropertyName = value;
- #if UNITY_5_6_OR_NEWER
- _propTexture = Shader.PropertyToID(_texturePropertyName);
- #endif
- _isDirty = true;
- }
- }
- }
- [SerializeField] Vector2 _offset = Vector2.zero;
- public Vector2 Offset
- {
- get { return _offset; }
- set { if (_offset != value) { _offset = value; _isDirty = true; } }
- }
- [SerializeField] Vector2 _scale = Vector2.one;
- public Vector2 Scale
- {
- get { return _scale; }
- set { if (_scale != value) { _scale = value; _isDirty = true; } }
- }
- private bool _isDirty = false;
- private Texture _lastTextureApplied;
- #if UNITY_5_6_OR_NEWER
- private int _propTexture;
- #endif
- private static int _propStereo;
- private static int _propAlphaPack;
- private static int _propApplyGamma;
- private static int _propLayout;
- private const string PropChromaTexName = "_ChromaTex";
- private static int _propChromaTex;
- private const string PropYpCbCrTransformName = "_YpCbCrTransform";
- private static int _propYpCbCrTransform;
- private const string PropUseYpCbCrName = "_UseYpCbCr";
- private static int _propUseYpCbCr;
- private static int _propCroppingScalars;
- private void Awake()
- {
- if (_propStereo == 0)
- {
- _propStereo = Shader.PropertyToID("Stereo");
- }
- if (_propAlphaPack == 0)
- {
- _propAlphaPack = Shader.PropertyToID("AlphaPack");
- }
- if (_propApplyGamma == 0)
- {
- _propApplyGamma = Shader.PropertyToID("_ApplyGamma");
- }
- if (_propLayout == 0)
- {
- _propLayout = Shader.PropertyToID("Layout");
- }
- if (_propChromaTex == 0)
- {
- _propChromaTex = Shader.PropertyToID(PropChromaTexName);
- }
- if (_propYpCbCrTransform == 0)
- {
- _propYpCbCrTransform = Shader.PropertyToID(PropYpCbCrTransformName);
- }
- if (_propUseYpCbCr == 0)
- {
- _propUseYpCbCr = Shader.PropertyToID(PropUseYpCbCrName);
- }
- if (_propCroppingScalars == 0)
- {
- _propCroppingScalars = Shader.PropertyToID("_CroppingScalars");
- }
- if (_media != null)
- {
- _media.Events.AddListener(OnMediaPlayerEvent);
- }
- }
- public void ForceUpdate()
- {
- _isDirty = true;
- LateUpdate();
- }
- // Callback function to handle events
- private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
- {
- switch (et)
- {
- case MediaPlayerEvent.EventType.FirstFrameReady:
- case MediaPlayerEvent.EventType.PropertiesChanged:
- ForceUpdate();
- break;
- }
- }
- private void ChangeMediaPlayer(MediaPlayer player)
- {
- if (_media != player)
- {
- if (_media != null)
- {
- _media.Events.RemoveListener(OnMediaPlayerEvent);
- }
- _media = player;
- if (_media != null)
- {
- _media.Events.AddListener(OnMediaPlayerEvent);
- }
- _isDirty = true;
- }
- }
- // We do a LateUpdate() to allow for any changes in the texture that may have happened in Update()
- private void LateUpdate()
- {
- bool applied = false;
- // Try to apply texture from media
- if (_media != null && _media.TextureProducer != null)
- {
- Texture resamplerTex = _media.FrameResampler == null || _media.FrameResampler.OutputTexture == null ? null : _media.FrameResampler.OutputTexture[0];
- Texture texture = _media.m_Resample ? resamplerTex : _media.TextureProducer.GetTexture(0);
- if (texture != null)
- {
- // Check for changing texture
- if (texture != _lastTextureApplied)
- {
- _isDirty = true;
- }
- if (_isDirty)
- {
- int planeCount = _media.m_Resample ? 1 : _media.TextureProducer.GetTextureCount();
- for (int plane = 0; plane < planeCount; plane++)
- {
- Texture resamplerTexPlane = _media.FrameResampler == null || _media.FrameResampler.OutputTexture == null ? null : _media.FrameResampler.OutputTexture[plane];
- texture = _media.m_Resample ? resamplerTexPlane : _media.TextureProducer.GetTexture(plane);
- if (texture != null)
- {
- ApplyMapping(texture, _media.TextureProducer.RequiresVerticalFlip(), plane);
- }
- }
- }
- applied = true;
- }
- }
- // If the media didn't apply a texture, then try to apply the default texture
- if (!applied)
- {
- if (_defaultTexture != _lastTextureApplied)
- {
- _isDirty = true;
- }
- if (_isDirty)
- {
- ApplyMapping(_defaultTexture, false);
- }
- }
- }
- private void ApplyMapping(Texture texture, bool requiresYFlip, int plane = 0)
- {
- if (_mesh != null)
- {
- _isDirty = false;
- Material[] meshMaterials = _mesh.materials;
- if (meshMaterials != null)
- {
- for (int i = 0; i < meshMaterials.Length; i++)
- {
- Material mat = meshMaterials[i];
- if (mat != null)
- {
- if (plane == 0)
- {
- #if UNITY_5_6_OR_NEWER
- mat.SetTexture(_propTexture, texture);
- #else
- mat.SetTexture(_texturePropertyName, texture);
- #endif
- _lastTextureApplied = texture;
- if (texture != null)
- {
- #if UNITY_5_6_OR_NEWER
- if (requiresYFlip)
- {
- mat.SetTextureScale(_propTexture, new Vector2(_scale.x, -_scale.y));
- mat.SetTextureOffset(_propTexture, Vector2.up + _offset);
- }
- else
- {
- mat.SetTextureScale(_propTexture, _scale);
- mat.SetTextureOffset(_propTexture, _offset);
- }
- #else
- if (requiresYFlip)
- {
- mat.SetTextureScale(_texturePropertyName, new Vector2(_scale.x, -_scale.y));
- mat.SetTextureOffset(_texturePropertyName, Vector2.up + _offset);
- }
- else
- {
- mat.SetTextureScale(_texturePropertyName, _scale);
- mat.SetTextureOffset(_texturePropertyName, _offset);
- }
- #endif
- }
- }
- else if (plane == 1)
- {
- if (mat.HasProperty(_propUseYpCbCr) && mat.HasProperty(_propChromaTex))
- {
- mat.EnableKeyword("USE_YPCBCR");
- mat.SetTexture(_propChromaTex, texture);
- mat.SetMatrix(_propYpCbCrTransform, _media.TextureProducer.GetYpCbCrTransform());
- #if UNITY_5_6_OR_NEWER
- if (requiresYFlip)
- {
- mat.SetTextureScale(_propChromaTex, new Vector2(_scale.x, -_scale.y));
- mat.SetTextureOffset(_propChromaTex, Vector2.up + _offset);
- }
- else
- {
- mat.SetTextureScale(_propChromaTex, _scale);
- mat.SetTextureOffset(_propChromaTex, _offset);
- }
- #else
- if (requiresYFlip)
- {
- mat.SetTextureScale(PropChromaTexName, new Vector2(_scale.x, -_scale.y));
- mat.SetTextureOffset(PropChromaTexName, Vector2.up + _offset);
- }
- else
- {
- mat.SetTextureScale(PropChromaTexName, _scale);
- mat.SetTextureOffset(PropChromaTexName, _offset);
- }
- #endif
- }
- }
- if (_media != null)
- {
- // Apply changes for layout
- if (mat.HasProperty(_propLayout))
- {
- Helper.SetupLayoutMaterial(mat, _media.VideoLayoutMapping);
- }
- // Apply changes for stereo videos
- if (mat.HasProperty(_propStereo))
- {
- Helper.SetupStereoMaterial(mat, _media.m_StereoPacking, _media.m_DisplayDebugStereoColorTint);
- }
- // Apply changes for alpha videos
- if (mat.HasProperty(_propAlphaPack))
- {
- Helper.SetupAlphaPackedMaterial(mat, _media.m_AlphaPacking);
- }
- #if UNITY_PLATFORM_SUPPORTS_LINEAR
- // Apply gamma
- if (mat.HasProperty(_propApplyGamma))
- {
- if (texture == _defaultTexture || _media.Info == null)
- {
- Helper.SetupGammaMaterial(mat, true);
- }
- else
- {
- Helper.SetupGammaMaterial(mat, _media.Info.PlayerSupportsLinearColorSpace());
- }
- }
- #else
- _propApplyGamma |= 0; // Prevent compiler warning about unused variable
- #endif
- #if (!UNITY_EDITOR && UNITY_ANDROID)
- // Adjust for cropping (when the decoder decodes in blocks that overrun the video frame size, it pads), OES only as we apply this lower down for none-OES
- if (_media.PlatformOptionsAndroid.useFastOesPath &&
- _media.Info != null &&
- mat.HasProperty(_propCroppingScalars) )
- {
- float[] transform = _media.Info.GetTextureTransform();
- if (transform != null)
- {
- mat.SetVector(_propCroppingScalars, new Vector4( transform[0], transform[3], 1.0f, 1.0f));
- }
- }
- #else
- _propCroppingScalars |= 0; // Prevent compiler warning about unused variable
- #endif
- }
- }
- }
- }
- }
- }
- private void OnEnable()
- {
- if (_mesh == null)
- {
- _mesh = this.GetComponent<MeshRenderer>();
- if (_mesh == null)
- {
- Debug.LogWarning("[AVProVideo] No mesh renderer set or found in gameobject");
- }
- }
- #if UNITY_5_6_OR_NEWER
- _propTexture = Shader.PropertyToID(_texturePropertyName);
- #endif
- _isDirty = true;
- if (_mesh != null)
- {
- LateUpdate();
- }
- }
- private void OnDisable()
- {
- ApplyMapping(_defaultTexture, false);
- }
- private void OnDestroy()
- {
- ChangeMediaPlayer(null);
- }
- }
- }
|