using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace RenderHeads.Media.AVProVideo { [ExecuteInEditMode] [HelpURL("http://renderheads.com/product/avpro-video/")] [AddComponentMenu("AVPro Video/Display uGUI", 200)] public class DisplayUGUI : MaskableGraphic { protected override void Awake() { if (DisplayUGUI._propAlphaPack == 0) { DisplayUGUI._propStereo = Shader.PropertyToID("Stereo"); DisplayUGUI._propAlphaPack = Shader.PropertyToID("AlphaPack"); DisplayUGUI._propVertScale = Shader.PropertyToID("_VertScale"); DisplayUGUI._propApplyGamma = Shader.PropertyToID("_ApplyGamma"); DisplayUGUI._propUseYpCbCr = Shader.PropertyToID("_UseYpCbCr"); DisplayUGUI._propChromaTex = Shader.PropertyToID("_ChromaTex"); } if (DisplayUGUI._shaderAlphaPacking == null) { DisplayUGUI._shaderAlphaPacking = Shader.Find("AVProVideo/UI/Transparent Packed"); if (DisplayUGUI._shaderAlphaPacking == null) { Debug.LogWarning("[AVProVideo] Missing shader AVProVideo/UI/Transparent Packed"); } } if (DisplayUGUI._shaderStereoPacking == null) { DisplayUGUI._shaderStereoPacking = Shader.Find("AVProVideo/UI/Stereo"); if (DisplayUGUI._shaderStereoPacking == null) { Debug.LogWarning("[AVProVideo] Missing shader AVProVideo/UI/Stereo"); } } base.Awake(); } protected override void Start() { this._userMaterial = (this.m_Material != null); base.Start(); } protected override void OnDestroy() { if (this._material != null) { this.material = null; UnityEngine.Object.Destroy(this._material); this._material = null; } base.OnDestroy(); } private Shader GetRequiredShader() { Shader shader = null; StereoPacking stereoPacking = this._mediaPlayer.m_StereoPacking; if (stereoPacking != StereoPacking.None) { if (stereoPacking == StereoPacking.LeftRight || stereoPacking == StereoPacking.TopBottom) { shader = DisplayUGUI._shaderStereoPacking; } } AlphaPacking alphaPacking = this._mediaPlayer.m_AlphaPacking; if (alphaPacking != AlphaPacking.None) { if (alphaPacking == AlphaPacking.LeftRight || alphaPacking == AlphaPacking.TopBottom) { shader = DisplayUGUI._shaderAlphaPacking; } } if (shader == null && this._mediaPlayer.Info != null && QualitySettings.activeColorSpace == ColorSpace.Linear && !this._mediaPlayer.Info.PlayerSupportsLinearColorSpace()) { shader = DisplayUGUI._shaderAlphaPacking; } if (shader == null && this._mediaPlayer.TextureProducer != null && this._mediaPlayer.TextureProducer.GetTextureCount() == 2) { shader = DisplayUGUI._shaderAlphaPacking; } return shader; } public override Texture mainTexture { get { Texture result = Texture2D.whiteTexture; if (this.HasValidTexture()) { Texture texture = (this._mediaPlayer.FrameResampler != null && this._mediaPlayer.FrameResampler.OutputTexture != null) ? this._mediaPlayer.FrameResampler.OutputTexture[0] : null; result = ((!this._mediaPlayer.m_Resample) ? this._mediaPlayer.TextureProducer.GetTexture(0) : texture); } else if (this._noDefaultDisplay) { result = null; } else if (this._defaultTexture != null) { result = this._defaultTexture; } return result; } } public bool HasValidTexture() { return this._mediaPlayer != null && this._mediaPlayer.TextureProducer != null && this._mediaPlayer.TextureProducer.GetTexture(0) != null; } private void UpdateInternalMaterial() { if (this._mediaPlayer != null) { Shader x = null; if (this._material != null) { x = this._material.shader; } Shader requiredShader = this.GetRequiredShader(); if (x != requiredShader) { if (this._material != null) { this.material = null; UnityEngine.Object.Destroy(this._material); this._material = null; } if (requiredShader != null) { this._material = new Material(requiredShader); } } this.material = this._material; } } private void LateUpdate() { if (this._setNativeSize) { this.SetNativeSize(); } if (this._lastTexture != this.mainTexture) { this._lastTexture = this.mainTexture; this.SetVerticesDirty(); } if (this.HasValidTexture() && this.mainTexture != null && (this.mainTexture.width != this._lastWidth || this.mainTexture.height != this._lastHeight)) { this._lastWidth = this.mainTexture.width; this._lastHeight = this.mainTexture.height; this.SetVerticesDirty(); } if (!this._userMaterial && Application.isPlaying) { this.UpdateInternalMaterial(); } if (this.material != null && this._mediaPlayer != null) { if (this.material.HasProperty(DisplayUGUI._propUseYpCbCr) && this._mediaPlayer.TextureProducer != null && this._mediaPlayer.TextureProducer.GetTextureCount() == 2) { this.material.EnableKeyword("USE_YPCBCR"); Texture texture = (this._mediaPlayer.FrameResampler != null && this._mediaPlayer.FrameResampler.OutputTexture != null) ? this._mediaPlayer.FrameResampler.OutputTexture[1] : null; this.material.SetTexture(DisplayUGUI._propChromaTex, (!this._mediaPlayer.m_Resample) ? this._mediaPlayer.TextureProducer.GetTexture(1) : texture); } if (this.material.HasProperty(DisplayUGUI._propAlphaPack)) { Helper.SetupAlphaPackedMaterial(this.material, this._mediaPlayer.m_AlphaPacking); if (this._flipY && this._mediaPlayer.m_AlphaPacking != AlphaPacking.None) { this.material.SetFloat(DisplayUGUI._propVertScale, -1f); } else { this.material.SetFloat(DisplayUGUI._propVertScale, 1f); } } if (this.material.HasProperty(DisplayUGUI._propStereo)) { Helper.SetupStereoMaterial(this.material, this._mediaPlayer.m_StereoPacking, this._mediaPlayer.m_DisplayDebugStereoColorTint); } if (this.material.HasProperty(DisplayUGUI._propApplyGamma) && this._mediaPlayer.Info != null) { Helper.SetupGammaMaterial(this.material, this._mediaPlayer.Info.PlayerSupportsLinearColorSpace()); } } this.SetMaterialDirty(); } public MediaPlayer CurrentMediaPlayer { get { return this._mediaPlayer; } set { if (this._mediaPlayer != value) { this._mediaPlayer = value; this.SetMaterialDirty(); } } } public Rect uvRect { get { return this.m_UVRect; } set { if (this.m_UVRect == value) { return; } this.m_UVRect = value; this.SetVerticesDirty(); } } [ContextMenu("Set Native Size")] public override void SetNativeSize() { Texture mainTexture = this.mainTexture; if (mainTexture != null) { int num = Mathf.RoundToInt((float)mainTexture.width * this.uvRect.width); int num2 = Mathf.RoundToInt((float)mainTexture.height * this.uvRect.height); if (this._mediaPlayer != null) { if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.LeftRight || this._mediaPlayer.m_StereoPacking == StereoPacking.LeftRight) { num /= 2; } else if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.TopBottom || this._mediaPlayer.m_StereoPacking == StereoPacking.TopBottom) { num2 /= 2; } } base.rectTransform.anchorMax = base.rectTransform.anchorMin; base.rectTransform.sizeDelta = new Vector2((float)num, (float)num2); } } protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); this._OnFillVBO(this._vertices); vh.AddUIVertexStream(this._vertices, DisplayUGUI.QuadIndices); } [Obsolete("This method is not called from Unity 5.2 and above")] protected override void OnFillVBO(List vbo) { this._OnFillVBO(vbo); } private void _OnFillVBO(List vbo) { this._flipY = false; if (this.HasValidTexture()) { this._flipY = this._mediaPlayer.TextureProducer.RequiresVerticalFlip(); } Rect uvrect = this.m_UVRect; Vector4 drawingDimensions = this.GetDrawingDimensions(this._scaleMode, ref uvrect); vbo.Clear(); UIVertex simpleVert = UIVertex.simpleVert; simpleVert.color = this.color; simpleVert.position = new Vector2(drawingDimensions.x, drawingDimensions.y); simpleVert.uv0 = new Vector2(uvrect.xMin, uvrect.yMin); if (this._flipY) { simpleVert.uv0 = new Vector2(uvrect.xMin, 1f - uvrect.yMin); } vbo.Add(simpleVert); simpleVert.position = new Vector2(drawingDimensions.x, drawingDimensions.w); simpleVert.uv0 = new Vector2(uvrect.xMin, uvrect.yMax); if (this._flipY) { simpleVert.uv0 = new Vector2(uvrect.xMin, 1f - uvrect.yMax); } vbo.Add(simpleVert); simpleVert.position = new Vector2(drawingDimensions.z, drawingDimensions.w); simpleVert.uv0 = new Vector2(uvrect.xMax, uvrect.yMax); if (this._flipY) { simpleVert.uv0 = new Vector2(uvrect.xMax, 1f - uvrect.yMax); } vbo.Add(simpleVert); simpleVert.position = new Vector2(drawingDimensions.z, drawingDimensions.y); simpleVert.uv0 = new Vector2(uvrect.xMax, uvrect.yMin); if (this._flipY) { simpleVert.uv0 = new Vector2(uvrect.xMax, 1f - uvrect.yMin); } vbo.Add(simpleVert); } private Vector4 GetDrawingDimensions(ScaleMode scaleMode, ref Rect uvRect) { Vector4 zero = Vector4.zero; if (this.mainTexture != null) { Vector4 zero2 = Vector4.zero; Vector2 vector = new Vector2((float)this.mainTexture.width, (float)this.mainTexture.height); if (this._mediaPlayer != null) { if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.LeftRight || this._mediaPlayer.m_StereoPacking == StereoPacking.LeftRight) { vector.x /= 2f; } else if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.TopBottom || this._mediaPlayer.m_StereoPacking == StereoPacking.TopBottom) { vector.y /= 2f; } } Rect pixelAdjustedRect = base.GetPixelAdjustedRect(); int num = Mathf.RoundToInt(vector.x); int num2 = Mathf.RoundToInt(vector.y); Vector4 vector2 = new Vector4(zero2.x / (float)num, zero2.y / (float)num2, ((float)num - zero2.z) / (float)num, ((float)num2 - zero2.w) / (float)num2); if (vector.sqrMagnitude > 0f) { if (scaleMode == ScaleMode.ScaleToFit) { float num3 = vector.x / vector.y; float num4 = pixelAdjustedRect.width / pixelAdjustedRect.height; if (num3 > num4) { float height = pixelAdjustedRect.height; pixelAdjustedRect.height = pixelAdjustedRect.width * (1f / num3); pixelAdjustedRect.y += (height - pixelAdjustedRect.height) * base.rectTransform.pivot.y; } else { float width = pixelAdjustedRect.width; pixelAdjustedRect.width = pixelAdjustedRect.height * num3; pixelAdjustedRect.x += (width - pixelAdjustedRect.width) * base.rectTransform.pivot.x; } } else if (scaleMode == ScaleMode.ScaleAndCrop) { float num5 = vector.x / vector.y; float num6 = pixelAdjustedRect.width / pixelAdjustedRect.height; if (num6 > num5) { float num7 = num5 / num6; uvRect = new Rect(0f, (1f - num7) * 0.5f, 1f, num7); } else { float num8 = num6 / num5; uvRect = new Rect(0.5f - num8 * 0.5f, 0f, num8, 1f); } } } zero = new Vector4(pixelAdjustedRect.x + pixelAdjustedRect.width * vector2.x, pixelAdjustedRect.y + pixelAdjustedRect.height * vector2.y, pixelAdjustedRect.x + pixelAdjustedRect.width * vector2.z, pixelAdjustedRect.y + pixelAdjustedRect.height * vector2.w); } return zero; } [SerializeField] public MediaPlayer _mediaPlayer; [SerializeField] public Rect m_UVRect = new Rect(0f, 0f, 1f, 1f); [SerializeField] public bool _setNativeSize; [SerializeField] public ScaleMode _scaleMode = ScaleMode.ScaleToFit; [SerializeField] public bool _noDefaultDisplay = true; [SerializeField] public bool _displayInEditor = true; [SerializeField] public Texture _defaultTexture; private int _lastWidth; private int _lastHeight; private bool _flipY; private Texture _lastTexture; private static Shader _shaderStereoPacking; private static Shader _shaderAlphaPacking; private static int _propAlphaPack; private static int _propVertScale; private static int _propStereo; private static int _propApplyGamma; private static int _propUseYpCbCr; private const string PropChromaTexName = "_ChromaTex"; private static int _propChromaTex; private bool _userMaterial = true; private Material _material; private List _vertices = new List(4); private static List QuadIndices = new List(new int[] { 0, 1, 2, 2, 3, 0 }); } }