first commit
This commit is contained in:
9
Assets/AVProVideo/Extensions/UnityUI/Editor.meta
Normal file
9
Assets/AVProVideo/Extensions/UnityUI/Editor.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b801737c3821d6e438ecf2a742d4f04b
|
||||
folderAsset: yes
|
||||
timeCreated: 1591797492
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
172
Assets/AVProVideo/Extensions/UnityUI/Editor/DisplayUGUIEditor.cs
Normal file
172
Assets/AVProVideo/Extensions/UnityUI/Editor/DisplayUGUIEditor.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
// UnityEngine.UI was moved to a package in 2019.2.0
|
||||
// Unfortunately no way to test for this across all Unity versions yet
|
||||
// You can set up the asmdef to reference the new package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
#define AVPRO_PACKAGE_UNITYUI
|
||||
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Editor for the DisplayUGUI component
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(DisplayUGUI), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class DisplayUGUIEditor : GraphicEditor
|
||||
{
|
||||
// Note we have precedence for calling rectangle for just rect, even in the Inspector.
|
||||
// For example in the Camera component's Viewport Rect.
|
||||
// Hence sticking with Rect here to be consistent with corresponding property in the API.
|
||||
private static readonly GUIContent m_guiTextUVRectContent = new GUIContent("UV Rect");
|
||||
|
||||
private SerializedProperty _propMediaPlayer;
|
||||
private SerializedProperty _propUVRect;
|
||||
private SerializedProperty _propDefaultTexture;
|
||||
private SerializedProperty _propNoDefaultDisplay;
|
||||
private SerializedProperty _propDisplayInEditor;
|
||||
private SerializedProperty _propSetNativeSize;
|
||||
private SerializedProperty _propScaleMode;
|
||||
|
||||
[MenuItem("GameObject/UI/AVPro Video uGUI", false, 0)]
|
||||
public static void CreateGameObject()
|
||||
{
|
||||
GameObject parent = Selection.activeGameObject;
|
||||
RectTransform parentCanvasRenderer = ( parent != null ) ? parent.GetComponent<RectTransform>() : null;
|
||||
if( parentCanvasRenderer )
|
||||
{
|
||||
GameObject go = new GameObject("AVPro Video");
|
||||
go.transform.SetParent(parent.transform, false);
|
||||
go.AddComponent<RectTransform>();
|
||||
go.AddComponent<CanvasRenderer>();
|
||||
go.AddComponent<DisplayUGUI>();
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("AVPro Video", "You must make the AVPro Video uGUI object as a child of a Canvas.", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RequiresConstantRepaint()
|
||||
{
|
||||
DisplayUGUI displayComponent = target as DisplayUGUI;
|
||||
return (displayComponent != null && displayComponent.HasValidTexture());
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
_propMediaPlayer = this.CheckFindProperty("_mediaPlayer");
|
||||
_propUVRect = this.CheckFindProperty("_uvRect");
|
||||
_propSetNativeSize = this.CheckFindProperty("_setNativeSize");
|
||||
_propScaleMode = this.CheckFindProperty("_scaleMode");
|
||||
_propNoDefaultDisplay = this.CheckFindProperty("_noDefaultDisplay");
|
||||
_propDisplayInEditor = this.CheckFindProperty("_displayInEditor");
|
||||
_propDefaultTexture = this.CheckFindProperty("_defaultTexture");
|
||||
|
||||
SetShowNativeSize(true);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(_propMediaPlayer);
|
||||
EditorGUILayout.PropertyField(_propDisplayInEditor);
|
||||
EditorGUILayout.PropertyField(_propNoDefaultDisplay);
|
||||
if (!_propNoDefaultDisplay.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propDefaultTexture);
|
||||
}
|
||||
AppearanceControlsGUI();
|
||||
RaycastControlsGUI();
|
||||
EditorGUILayout.PropertyField(_propUVRect, m_guiTextUVRectContent);
|
||||
|
||||
EditorGUILayout.PropertyField(_propSetNativeSize);
|
||||
EditorGUILayout.PropertyField(_propScaleMode);
|
||||
|
||||
SetShowNativeSize(false);
|
||||
NativeSizeButtonGUI();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void SetShowNativeSize(bool instant)
|
||||
{
|
||||
base.SetShowNativeSize(_propMediaPlayer.objectReferenceValue != null, instant);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow the texture to be previewed.
|
||||
/// </summary>
|
||||
public override bool HasPreviewGUI()
|
||||
{
|
||||
DisplayUGUI rawImage = target as DisplayUGUI;
|
||||
return rawImage != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the Image preview.
|
||||
/// </summary>
|
||||
public override void OnPreviewGUI(Rect drawArea, GUIStyle background)
|
||||
{
|
||||
DisplayUGUI rawImage = target as DisplayUGUI;
|
||||
Texture tex = rawImage.mainTexture;
|
||||
|
||||
if (tex == null)
|
||||
return;
|
||||
|
||||
// Create the texture rectangle that is centered inside rect.
|
||||
Rect outerRect = drawArea;
|
||||
|
||||
Matrix4x4 m = GUI.matrix;
|
||||
// Flip the image vertically
|
||||
if (rawImage.HasValidTexture())
|
||||
{
|
||||
if (rawImage.Player.TextureProducer.RequiresVerticalFlip())
|
||||
{
|
||||
GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0f, outerRect.y + (outerRect.height / 2f)));
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.DrawTextureTransparent(outerRect, tex, ScaleMode.ScaleToFit);//, outer.width / outer.height);
|
||||
//SpriteDrawUtility.DrawSprite(tex, rect, outer, rawImage.uvRect, rawImage.canvasRenderer.GetColor());
|
||||
|
||||
GUI.matrix = m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info String drawn at the bottom of the Preview
|
||||
/// </summary>
|
||||
public override string GetInfoString()
|
||||
{
|
||||
DisplayUGUI rawImage = target as DisplayUGUI;
|
||||
|
||||
string text = string.Empty;
|
||||
if (rawImage.HasValidTexture())
|
||||
{
|
||||
text += string.Format("Video Size: {0}x{1}\n",
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.mainTexture.width)),
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.mainTexture.height)));
|
||||
}
|
||||
|
||||
// Image size Text
|
||||
text += string.Format("Display Size: {0}x{1}",
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.width)),
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.height)));
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e20933bfdb909544b98bc0de2926c4c
|
||||
timeCreated: 1438726873
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "AVProVideo.Extensions.UnityUI.Editor",
|
||||
"references": [
|
||||
"AVProVideo.Runtime",
|
||||
"AVProVideo.Editor",
|
||||
"AVProVideo.Extensions.UnityUI"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 163aa7dfc21664e47a9d1ce803fb3e3f
|
||||
timeCreated: 1591797492
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/AVProVideo/Extensions/UnityUI/Runtime.meta
Normal file
9
Assets/AVProVideo/Extensions/UnityUI/Runtime.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d60008e579848de489d8104d999e0afa
|
||||
folderAsset: yes
|
||||
timeCreated: 1591797614
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
715
Assets/AVProVideo/Extensions/UnityUI/Runtime/DisplayUGUI.cs
Normal file
715
Assets/AVProVideo/Extensions/UnityUI/Runtime/DisplayUGUI.cs
Normal file
@@ -0,0 +1,715 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2025 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// UnityEngine.UI was moved to a package in 2019.2.0
|
||||
// Unfortunately no way to test for this across all Unity versions yet
|
||||
// You can set up the asmdef to reference the new package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
#define AVPRO_PACKAGE_UNITYUI
|
||||
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
|
||||
|
||||
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS
|
||||
#define UNITY_PLATFORM_SUPPORTS_YPCBCR
|
||||
#endif
|
||||
|
||||
#define UNITY_PLATFORM_SUPPORTS_LINEAR
|
||||
|
||||
#if (!UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN) && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || UNITY_ANDROID)
|
||||
#define UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
#endif
|
||||
|
||||
#if (UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN))
|
||||
#define UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO
|
||||
#endif
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays the video from MediaPlayer component using uGUI
|
||||
/// </summary>
|
||||
[HelpURL("http://renderheads.com/products/avpro-video/")]
|
||||
[AddComponentMenu("AVPro Video/Display uGUI", 200)]
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
//[ExecuteInEditMode]
|
||||
public class DisplayUGUI : MaskableGraphic
|
||||
{
|
||||
[SerializeField] MediaPlayer _mediaPlayer;
|
||||
|
||||
public MediaPlayer Player
|
||||
{
|
||||
get { return _mediaPlayer; }
|
||||
set { ChangeMediaPlayer(value); }
|
||||
}
|
||||
|
||||
[Tooltip("Default texture to display when the video texture is preparing")]
|
||||
[SerializeField] Texture _defaultTexture;
|
||||
|
||||
public Texture DefaultTexture
|
||||
{
|
||||
get { return _defaultTexture; }
|
||||
set { if (_defaultTexture != value) { _defaultTexture = value; } }
|
||||
}
|
||||
|
||||
[FormerlySerializedAs("m_UVRect")]
|
||||
[SerializeField] Rect _uvRect = new Rect(0f, 0f, 1f, 1f);
|
||||
|
||||
public Rect UVRect
|
||||
{
|
||||
get { return _uvRect; }
|
||||
set { _uvRect = value; }
|
||||
}
|
||||
|
||||
[SerializeField] bool _setNativeSize = false;
|
||||
|
||||
public bool ApplyNativeSize
|
||||
{
|
||||
get { return _setNativeSize; }
|
||||
set { _setNativeSize = value; }
|
||||
}
|
||||
|
||||
[SerializeField] ScaleMode _scaleMode = ScaleMode.ScaleToFit;
|
||||
|
||||
public ScaleMode ScaleMode
|
||||
{
|
||||
get { return _scaleMode; }
|
||||
set { _scaleMode = value; }
|
||||
}
|
||||
|
||||
[SerializeField] bool _noDefaultDisplay = true;
|
||||
|
||||
public bool NoDefaultDisplay
|
||||
{
|
||||
get { return _noDefaultDisplay; }
|
||||
set { _noDefaultDisplay = value; }
|
||||
}
|
||||
|
||||
[SerializeField] bool _displayInEditor = true;
|
||||
|
||||
public bool DisplayInEditor
|
||||
{
|
||||
get { return _displayInEditor; }
|
||||
set { _displayInEditor = value; }
|
||||
}
|
||||
|
||||
private int _lastWidth;
|
||||
private int _lastHeight;
|
||||
private Orientation _lastOrientation;
|
||||
private bool _flipY;
|
||||
private Texture _lastTexture;
|
||||
private static Shader _shaderStereoPacking;
|
||||
private static Shader _shaderAlphaPacking;
|
||||
private static Shader _shaderAndroidOES;
|
||||
private static Shader _shaderAndroidOESAlphaPacking;
|
||||
|
||||
private bool _isUserMaterial = true;
|
||||
private Material _material;
|
||||
|
||||
private List<UIVertex> _vertices = new List<UIVertex>(4);
|
||||
private static List<int> QuadIndices = new List<int>(new int[] { 0, 1, 2, 2, 3, 0 });
|
||||
|
||||
private Vector4 _drawingDimensions = Vector4.zero;
|
||||
|
||||
public Vector4 DrawingDimensions
|
||||
{
|
||||
get => _drawingDimensions;
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
}
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
// Callback function to handle events
|
||||
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
|
||||
{
|
||||
switch (et)
|
||||
{
|
||||
case MediaPlayerEvent.EventType.FirstFrameReady:
|
||||
if (_isUserMaterial && null != GetRequiredShader())
|
||||
{
|
||||
Debug.LogWarning("[AVProVideo] Custom material is being used but the video requires our internal shader for correct rendering. Consider removing custom shader or modifying it for AVPro Video support.", this);
|
||||
}
|
||||
LateUpdate();
|
||||
break;
|
||||
case MediaPlayerEvent.EventType.PropertiesChanged:
|
||||
case MediaPlayerEvent.EventType.ResolutionChanged:
|
||||
case MediaPlayerEvent.EventType.Closing:
|
||||
LateUpdate();
|
||||
break;
|
||||
}
|
||||
// TODO: remove this, we're just doing this so we can make sure texture is correct when running in EDIT mode
|
||||
LateUpdate();
|
||||
}
|
||||
|
||||
private void ChangeMediaPlayer(MediaPlayer player)
|
||||
{
|
||||
if (_mediaPlayer != player)
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
|
||||
}
|
||||
_mediaPlayer = player;
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
}
|
||||
LateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private static Shader EnsureShader(Shader shader, string name)
|
||||
{
|
||||
if (shader == null)
|
||||
{
|
||||
shader = Shader.Find(name);
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogWarning("[AVProVideo] Missing shader " + name);
|
||||
}
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
private static Shader EnsureAlphaPackingShader()
|
||||
{
|
||||
_shaderAlphaPacking = EnsureShader(_shaderAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo)");
|
||||
return _shaderAlphaPacking;
|
||||
}
|
||||
|
||||
private static Shader EnsureStereoPackingShader()
|
||||
{
|
||||
_shaderStereoPacking = EnsureShader(_shaderStereoPacking, "AVProVideo/Internal/UI/Stereo");
|
||||
return _shaderStereoPacking;
|
||||
}
|
||||
|
||||
private Shader EnsureAndroidOESShader()
|
||||
{
|
||||
_shaderAndroidOES = EnsureShader(_shaderAndroidOES, "AVProVideo/Internal/UI/Stereo - AndroidOES");
|
||||
return _shaderAndroidOES;
|
||||
}
|
||||
|
||||
private static Shader EnsureAndroidOESAlphaPackingShader()
|
||||
{
|
||||
_shaderAndroidOESAlphaPacking = EnsureShader(_shaderAndroidOESAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo) - AndroidOES");
|
||||
return _shaderAndroidOESAlphaPacking;
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
_isUserMaterial = (this.m_Material != null);
|
||||
if (_isUserMaterial)
|
||||
{
|
||||
_material = new Material(this.material);
|
||||
this.material = _material;
|
||||
}
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
// Destroy existing material
|
||||
if (_material != null)
|
||||
{
|
||||
this.material = null;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
Material.DestroyImmediate(_material);
|
||||
#else
|
||||
Material.Destroy(_material);
|
||||
#endif
|
||||
_material = null;
|
||||
}
|
||||
ChangeMediaPlayer(null);
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
private Shader GetRequiredShader()
|
||||
{
|
||||
Shader result = null;
|
||||
|
||||
if (result == null && _mediaPlayer.TextureProducer != null)
|
||||
{
|
||||
switch (_mediaPlayer.TextureProducer.GetTextureStereoPacking())
|
||||
{
|
||||
case StereoPacking.Monoscopic:
|
||||
break;
|
||||
case StereoPacking.LeftRight:
|
||||
case StereoPacking.TopBottom:
|
||||
case StereoPacking.MultiviewLeftPrimary:
|
||||
case StereoPacking.MultiviewRightPrimary:
|
||||
result = EnsureStereoPackingShader();
|
||||
break;
|
||||
}
|
||||
|
||||
if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)
|
||||
{
|
||||
result = EnsureAlphaPackingShader();
|
||||
}
|
||||
|
||||
switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())
|
||||
{
|
||||
case AlphaPacking.None:
|
||||
break;
|
||||
case AlphaPacking.LeftRight:
|
||||
case AlphaPacking.TopBottom:
|
||||
result = EnsureAlphaPackingShader();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_PLATFORM_SUPPORTS_LINEAR
|
||||
if (result == null && _mediaPlayer.Info != null)
|
||||
{
|
||||
if (QualitySettings.activeColorSpace == ColorSpace.Linear && !_mediaPlayer.Info.PlayerSupportsLinearColorSpace())
|
||||
{
|
||||
result = EnsureAlphaPackingShader();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (result == null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTextureCount() == 2)
|
||||
{
|
||||
result = EnsureAlphaPackingShader();
|
||||
}
|
||||
|
||||
// if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath() && (_defaultTexture == null || _lastTexture != _defaultTexture ))
|
||||
if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath())
|
||||
{
|
||||
// This shader handles stereo too
|
||||
result = EnsureAndroidOESShader();
|
||||
|
||||
if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)
|
||||
{
|
||||
result = EnsureAndroidOESAlphaPackingShader();
|
||||
}
|
||||
switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())
|
||||
{
|
||||
case AlphaPacking.None:
|
||||
break;
|
||||
case AlphaPacking.LeftRight:
|
||||
case AlphaPacking.TopBottom:
|
||||
result = EnsureAndroidOESAlphaPackingShader();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the texture used to draw this Graphic.
|
||||
/// </summary>
|
||||
public override Texture mainTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
Texture result = Texture2D.whiteTexture;
|
||||
if (HasValidTexture())
|
||||
{
|
||||
Texture resamplerTex = _mediaPlayer.FrameResampler == null || _mediaPlayer.FrameResampler.OutputTexture == null ? null : _mediaPlayer.FrameResampler.OutputTexture[0];
|
||||
result = _mediaPlayer.UseResampler ? resamplerTex : _mediaPlayer.TextureProducer.GetTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_noDefaultDisplay)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else if (_defaultTexture != null)
|
||||
{
|
||||
result = _defaultTexture;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (result == null && _displayInEditor)
|
||||
{
|
||||
result = Resources.Load<Texture2D>("AVProVideoIcon");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasValidTexture()
|
||||
{
|
||||
return (Application.isPlaying && _mediaPlayer != null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTexture() != null);
|
||||
}
|
||||
|
||||
private void UpdateInternalMaterial()
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.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);
|
||||
}
|
||||
}
|
||||
|
||||
this.material = _material;
|
||||
}
|
||||
}
|
||||
|
||||
// We do a LateUpdate() to allow for any changes in the texture that may have happened in Update()
|
||||
void LateUpdate()
|
||||
{
|
||||
if (_setNativeSize)
|
||||
{
|
||||
SetNativeSize();
|
||||
}
|
||||
|
||||
if (_lastTexture != mainTexture)
|
||||
{
|
||||
_lastTexture = mainTexture;
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
|
||||
if (HasValidTexture())
|
||||
{
|
||||
if (mainTexture != null)
|
||||
{
|
||||
Orientation orientation = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
|
||||
if (mainTexture.width != _lastWidth || mainTexture.height != _lastHeight || orientation != _lastOrientation)
|
||||
{
|
||||
_lastWidth = mainTexture.width;
|
||||
_lastHeight = mainTexture.height;
|
||||
_lastOrientation = orientation;
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
if (!_isUserMaterial)
|
||||
{
|
||||
UpdateInternalMaterial();
|
||||
}
|
||||
}
|
||||
|
||||
if (material != null && _mediaPlayer != null)
|
||||
{
|
||||
// TODO: only run when dirty
|
||||
VideoRender.SetupMaterialForMedia(materialForRendering, _mediaPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Texture to be used.
|
||||
/// </summary>
|
||||
public MediaPlayer CurrentMediaPlayer
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mediaPlayer;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_mediaPlayer != value)
|
||||
{
|
||||
_mediaPlayer = value;
|
||||
//SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UV rectangle used by the texture.
|
||||
/// </summary>
|
||||
public Rect uvRect
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uvRect;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_uvRect == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_uvRect = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjust the scale of the Graphic to make it pixel-perfect.
|
||||
/// </summary>
|
||||
[ContextMenu("Set Native Size")]
|
||||
public override void SetNativeSize()
|
||||
{
|
||||
Texture tex = mainTexture;
|
||||
if (tex != null)
|
||||
{
|
||||
int w = Mathf.RoundToInt(tex.width * uvRect.width);
|
||||
int h = Mathf.RoundToInt(tex.height * uvRect.height);
|
||||
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)
|
||||
if (_mediaPlayer.Info != null)
|
||||
{
|
||||
Orientation ori = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
|
||||
if (ori == Orientation.Portrait || ori == Orientation.PortraitFlipped)
|
||||
{
|
||||
w = Mathf.RoundToInt(tex.height * uvRect.width);
|
||||
h = Mathf.RoundToInt(tex.width * uvRect.height);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (_mediaPlayer.TextureProducer != null)
|
||||
{
|
||||
if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)
|
||||
{
|
||||
w /= 2;
|
||||
}
|
||||
else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)
|
||||
{
|
||||
h /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectTransform.anchorMax = rectTransform.anchorMin;
|
||||
rectTransform.sizeDelta = new Vector2(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
vh.Clear();
|
||||
|
||||
_OnFillVBO(_vertices);
|
||||
|
||||
vh.AddUIVertexStream(_vertices, QuadIndices );
|
||||
}
|
||||
|
||||
private void _OnFillVBO(List<UIVertex> vbo)
|
||||
{
|
||||
_flipY = false;
|
||||
if (HasValidTexture())
|
||||
{
|
||||
_flipY = _mediaPlayer.TextureProducer.RequiresVerticalFlip();
|
||||
}
|
||||
|
||||
Rect uvRect = _uvRect;
|
||||
Vector4 v = GetDrawingDimensions(_scaleMode, ref uvRect);
|
||||
_drawingDimensions = v;
|
||||
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
Matrix4x4 m = Matrix4x4.identity;
|
||||
if (HasValidTexture())
|
||||
{
|
||||
m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));
|
||||
}
|
||||
#endif
|
||||
|
||||
vbo.Clear();
|
||||
|
||||
var vert = UIVertex.simpleVert;
|
||||
vert.color = color;
|
||||
|
||||
vert.position = new Vector2(v.x, v.y);
|
||||
|
||||
vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMin);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMin);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
|
||||
vert.position = new Vector2(v.x, v.w);
|
||||
vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMax);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMax);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
|
||||
vert.position = new Vector2(v.z, v.w);
|
||||
vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMax);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMax);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
|
||||
vert.position = new Vector2(v.z, v.y);
|
||||
vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMin);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMin);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
}
|
||||
|
||||
private Vector4 GetDrawingDimensions(ScaleMode scaleMode, ref Rect uvRect)
|
||||
{
|
||||
Vector4 returnSize = Vector4.zero;
|
||||
|
||||
if (mainTexture != null)
|
||||
{
|
||||
var padding = Vector4.zero;
|
||||
|
||||
var textureSize = new Vector2(mainTexture.width, mainTexture.height);
|
||||
{
|
||||
// Adjust textureSize based on orientation
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)
|
||||
if (HasValidTexture())
|
||||
{
|
||||
Matrix4x4 m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));
|
||||
textureSize = m.MultiplyVector(textureSize);
|
||||
textureSize.x = Mathf.Abs(textureSize.x);
|
||||
textureSize.y = Mathf.Abs(textureSize.y);
|
||||
}
|
||||
#endif
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO
|
||||
if (HasValidTexture())
|
||||
{
|
||||
float par = _mediaPlayer.TextureProducer.GetTexturePixelAspectRatio();
|
||||
if (par > 0f)
|
||||
{
|
||||
if (par > 1f)
|
||||
{
|
||||
textureSize.x *= par;
|
||||
}
|
||||
else
|
||||
{
|
||||
textureSize.y /= par;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Adjust textureSize based on alpha/stereo packing
|
||||
if (_mediaPlayer != null && _mediaPlayer.TextureProducer != null)
|
||||
{
|
||||
if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)
|
||||
{
|
||||
textureSize.x /= 2;
|
||||
}
|
||||
else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)
|
||||
{
|
||||
textureSize.y /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rect r = GetPixelAdjustedRect();
|
||||
|
||||
// Fit the above textureSize into rectangle r
|
||||
int spriteW = Mathf.RoundToInt( textureSize.x );
|
||||
int spriteH = Mathf.RoundToInt( textureSize.y );
|
||||
|
||||
var size = new Vector4( padding.x / spriteW,
|
||||
padding.y / spriteH,
|
||||
(spriteW - padding.z) / spriteW,
|
||||
(spriteH - padding.w) / spriteH );
|
||||
|
||||
|
||||
{
|
||||
if (textureSize.sqrMagnitude > 0.0f)
|
||||
{
|
||||
if (scaleMode == ScaleMode.ScaleToFit)
|
||||
{
|
||||
float spriteRatio = textureSize.x / textureSize.y;
|
||||
float rectRatio = r.width / r.height;
|
||||
|
||||
if (spriteRatio > rectRatio)
|
||||
{
|
||||
float oldHeight = r.height;
|
||||
r.height = r.width * (1.0f / spriteRatio);
|
||||
r.y += (oldHeight - r.height) * rectTransform.pivot.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
float oldWidth = r.width;
|
||||
r.width = r.height * spriteRatio;
|
||||
r.x += (oldWidth - r.width) * rectTransform.pivot.x;
|
||||
}
|
||||
}
|
||||
else if (scaleMode == ScaleMode.ScaleAndCrop)
|
||||
{
|
||||
float aspectRatio = textureSize.x / textureSize.y;
|
||||
float screenRatio = r.width / r.height;
|
||||
if (screenRatio > aspectRatio)
|
||||
{
|
||||
float adjust = aspectRatio / screenRatio;
|
||||
uvRect = new Rect(uvRect.xMin, (uvRect.yMin * adjust) + (1f - adjust) * 0.5f, uvRect.width, adjust * uvRect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float adjust = screenRatio / aspectRatio;
|
||||
uvRect = new Rect(uvRect.xMin * adjust + (0.5f - adjust * 0.5f), uvRect.yMin, adjust * uvRect.width, uvRect.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
returnSize = new Vector4( r.x + r.width * size.x,
|
||||
r.y + r.height * size.y,
|
||||
r.x + r.width * size.z,
|
||||
r.y + r.height * size.w );
|
||||
|
||||
}
|
||||
|
||||
return returnSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f17cdc186456a4469a139a104d2ca72
|
||||
timeCreated: 1544813301
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
Assets/AVProVideo/Extensions/UnityUI/Runtime/SubtitlesUGUI.cs
Normal file
130
Assets/AVProVideo/Extensions/UnityUI/Runtime/SubtitlesUGUI.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Update a standard uGUI Text element with subtitle text as it plays from the MediaPlayer
|
||||
/// </summary>
|
||||
[AddComponentMenu("AVPro Video/Subtitles uGUI", 201)]
|
||||
[HelpURL("http://renderheads.com/products/avpro-video/")]
|
||||
public class SubtitlesUGUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] MediaPlayer _mediaPlayer = null;
|
||||
[SerializeField] Text _text = null;
|
||||
[SerializeField] Image _backgroundImage = null;
|
||||
[SerializeField] int _backgroundHorizontalPadding = 32;
|
||||
[SerializeField] int _backgroundVerticalPadding = 16;
|
||||
[SerializeField, Range(-1, 1024)] int _maxCharacters = 256;
|
||||
|
||||
public MediaPlayer Player
|
||||
{
|
||||
set { ChangeMediaPlayer(value); }
|
||||
get { return _mediaPlayer; }
|
||||
}
|
||||
|
||||
public Text Text
|
||||
{
|
||||
set { _text = value; }
|
||||
get { return _text; }
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
ChangeMediaPlayer(_mediaPlayer);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
ChangeMediaPlayer(null);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// TODO: Currently we need to call this each frame, as when it is called right after SetText()
|
||||
// the ContentSizeFitter hasn't run yet, so effectively the box is a frame behind.
|
||||
UpdateBackgroundRect();
|
||||
}
|
||||
|
||||
public void ChangeMediaPlayer(MediaPlayer newPlayer)
|
||||
{
|
||||
// When changing the media player, handle event subscriptions
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
|
||||
_mediaPlayer = null;
|
||||
}
|
||||
|
||||
SetText(string.Empty);
|
||||
|
||||
if (newPlayer != null)
|
||||
{
|
||||
newPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
_mediaPlayer = newPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetText(string text)
|
||||
{
|
||||
_text.text = text;
|
||||
UpdateBackgroundRect();
|
||||
}
|
||||
|
||||
private string PrepareText(string text)
|
||||
{
|
||||
// Crop text that is too long
|
||||
if (_maxCharacters >= 0 && text.Length > _maxCharacters)
|
||||
{
|
||||
text = text.Substring(0, _maxCharacters);
|
||||
}
|
||||
|
||||
// Change RichText for Unity uGUI Text
|
||||
text = text.Replace("<font color=", "<color=");
|
||||
text = text.Replace("</font>", "</color>");
|
||||
text = text.Replace("<u>", string.Empty);
|
||||
text = text.Replace("</u>", string.Empty);
|
||||
return text;
|
||||
}
|
||||
|
||||
private void UpdateBackgroundRect()
|
||||
{
|
||||
if (_backgroundImage)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_text.text))
|
||||
{
|
||||
_backgroundImage.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundImage.enabled = true;
|
||||
_backgroundImage.rectTransform.sizeDelta = _text.rectTransform.sizeDelta;
|
||||
_backgroundImage.rectTransform.anchoredPosition = _text.rectTransform.anchoredPosition;
|
||||
_backgroundImage.rectTransform.offsetMin -= new Vector2(_backgroundHorizontalPadding, _backgroundVerticalPadding);
|
||||
_backgroundImage.rectTransform.offsetMax += new Vector2(_backgroundHorizontalPadding, _backgroundVerticalPadding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback function to handle events
|
||||
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
|
||||
{
|
||||
switch (et)
|
||||
{
|
||||
case MediaPlayerEvent.EventType.Closing:
|
||||
{
|
||||
SetText(string.Empty);
|
||||
break;
|
||||
}
|
||||
case MediaPlayerEvent.EventType.SubtitleChange:
|
||||
{
|
||||
SetText(PrepareText(_mediaPlayer.Subtitles.GetSubtitleText()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d4bbe43657314a49a5f730e66dafebd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
|
||||
userData:
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "AVProVideo.Extensions.UnityUI",
|
||||
"references": [
|
||||
"AVProVideo.Runtime"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3bd657f68851a7f448c82186c6797ee0
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user