| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 | #if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS	#define UNITY_PLATFORM_SUPPORTS_YPCBCR#endif#if UNITY_EDITOR || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || UNITY_ANDROID || (UNITY_WEBGL && UNITY_2017_2_OR_NEWER)	#define UNITY_PLATFORM_SUPPORTS_LINEAR#endifusing System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.Rendering;//-----------------------------------------------------------------------------// Copyright 2015-2024 RenderHeads Ltd.  All rights reserved.//-----------------------------------------------------------------------------namespace RenderHeads.Media.AVProVideo{#if AVPRO_FEATURE_VIDEORESOLVE	[System.Serializable]	public class VideoResolve : ITextureProducer	{		[SerializeField] VideoResolveOptions _options = VideoResolveOptions.Create();		[SerializeField] RenderTexture _targetRenderTexture = null;		[SerializeField] ScaleMode _targetRenderTextureScale = ScaleMode.ScaleToFit;		void SetSource(ITextureProducer textureSource)		{			//_commandBuffer.IssuePluginEvent(blahCallback, 0);			//Graphics.ExecuteCommandBuffer(_commandBuffer);		}		// ITextureProducer implementation		/// <inheritdoc/>		public int GetTextureCount() { return 1; }		/// <inheritdoc/>		public Texture GetTexture(int index = 0) { return _texture; }		/// <inheritdoc/>		public int GetTextureFrameCount() { return _textureSource.GetTextureFrameCount(); }		/// <inheritdoc/>		public bool SupportsTextureFrameCount() { return _textureSource.SupportsTextureFrameCount(); }		/// <inheritdoc/>		public long GetTextureTimeStamp() { return _textureSource.GetTextureTimeStamp(); }		/// <inheritdoc/>		public bool RequiresVerticalFlip() { return false; }		/// <inheritdoc/>		public StereoPacking GetTextureStereoPacking() { return StereoPacking.None; }		/// <inheritdoc/>		public TransparencyMode GetTextureTransparency() { return TransparencyMode.Transparent; }		/// <inheritdoc/>		public AlphaPacking GetTextureAlphaPacking() { return AlphaPacking.None; }		/// <inheritdoc/>		public Matrix4x4 GetYpCbCrTransform() { return Matrix4x4.identity; }		private ITextureProducer _textureSource;		private Texture _texture;		private CommandBuffer _commandBuffer;	}#endif	public struct LazyShaderProperty	{		public LazyShaderProperty(string name)		{			_name = name;			_id = 0;		}		public string Name { get { return _name;} }		public int Id { get { if (_id == 0) { _id = Shader.PropertyToID(_name); } return _id; } }		private string _name;		private int _id;	}	/// <summary>Helper class for everything related to setting up materials for rendering/resolving videos</summary>	public class VideoRender	{		public const string Shader_IMGUI = "AVProVideo/Internal/IMGUI/Texture Transparent";		public const string Shader_Resolve = "AVProVideo/Internal/Resolve";		public const string Shader_ResolveOES = "AVProVideo/Internal/ResolveOES";		public const string Shader_Preview = "AVProVideo/Internal/Preview";	#if UNITY_PLATFORM_SUPPORTS_YPCBCR		public const string Keyword_UseYpCbCr = "USE_YPCBCR";	#endif		public const string Keyword_AlphaPackTopBottom = "ALPHAPACK_TOP_BOTTOM";		public const string Keyword_AlphaPackLeftRight = "ALPHAPACK_LEFT_RIGHT";		public const string Keyword_AlphaPackNone = "ALPHAPACK_NONE";		public const string Keyword_StereoTopBottom = "STEREO_TOP_BOTTOM";		public const string Keyword_StereoLeftRight = "STEREO_LEFT_RIGHT";		public const string Keyword_StereoCustomUV = "STEREO_CUSTOM_UV";		public const string Keyword_StereoTwoTextures = "STEREO_TWOTEXTURES";		public const string Keyword_StereoNone = "MONOSCOPIC";		public const string Keyword_StereoDebug = "STEREO_DEBUG";		public const string Keyword_LayoutEquirect180 = "LAYOUT_EQUIRECT180";		public const string Keyword_LayoutNone = "LAYOUT_NONE";		public const string Keyword_ForceEyeNone = "FORCEEYE_NONE";		public const string Keyword_ForceEyeLeft = "FORCEEYE_LEFT";		public const string Keyword_ForceEyeRight = "FORCEEYE_RIGHT";		public const string Keyword_ApplyGamma = "APPLY_GAMMA";		public static readonly LazyShaderProperty PropChromaTex = new LazyShaderProperty("_ChromaTex");	#if UNITY_PLATFORM_SUPPORTS_YPCBCR		public static readonly LazyShaderProperty PropYpCbCrTransform = new LazyShaderProperty("_YpCbCrTransform");		public static readonly LazyShaderProperty PropUseYpCbCr = new LazyShaderProperty("_UseYpCbCr");	#endif		public static readonly LazyShaderProperty PropVertScale = new LazyShaderProperty("_VertScale");		public static readonly LazyShaderProperty PropApplyGamma = new LazyShaderProperty("_ApplyGamma");		public static readonly LazyShaderProperty PropStereo = new LazyShaderProperty("Stereo");		public static readonly LazyShaderProperty PropAlphaPack = new LazyShaderProperty("AlphaPack");		public static readonly LazyShaderProperty PropLayout = new LazyShaderProperty("Layout");		public static readonly LazyShaderProperty PropViewMatrix = new LazyShaderProperty("_ViewMatrix");		public static readonly LazyShaderProperty PropTextureMatrix = new LazyShaderProperty("_MainTex_Xfrm");		public static string Keyword_UseHSBC = "USE_HSBC";		public static readonly LazyShaderProperty PropHue = new LazyShaderProperty("_Hue");		public static readonly LazyShaderProperty PropSaturation = new LazyShaderProperty("_Saturation");		public static readonly LazyShaderProperty PropContrast = new LazyShaderProperty("_Contrast");		public static readonly LazyShaderProperty PropBrightness = new LazyShaderProperty("_Brightness");		public static readonly LazyShaderProperty PropInvGamma = new LazyShaderProperty("_InvGamma");		public static Material CreateResolveMaterial(bool usingAndroidOES)		{			return new Material(Shader.Find( usingAndroidOES ? VideoRender.Shader_ResolveOES : VideoRender.Shader_Resolve ));		}		public static Material CreateIMGUIMaterial()		{			return new Material(Shader.Find(VideoRender.Shader_Preview));		}		public static void SetupLayoutMaterial(Material material, VideoMapping mapping)		{			switch (mapping)			{				default:					material.DisableKeyword(Keyword_LayoutEquirect180);					material.EnableKeyword(Keyword_LayoutNone);					break;				// Only EquiRectangular180 currently does anything in the shader				case VideoMapping.EquiRectangular180:					material.DisableKeyword(Keyword_LayoutNone);					material.EnableKeyword(Keyword_LayoutEquirect180);					break;			}		}		public static void SetupStereoEyeModeMaterial(Material material, StereoEye mode)		{			switch (mode)			{				case StereoEye.Both:					material.DisableKeyword(Keyword_ForceEyeLeft);					material.DisableKeyword(Keyword_ForceEyeRight);					material.EnableKeyword(Keyword_ForceEyeNone);					break;				case StereoEye.Left:					material.DisableKeyword(Keyword_ForceEyeNone);					material.DisableKeyword(Keyword_ForceEyeRight);					material.EnableKeyword(Keyword_ForceEyeLeft);					break;				case StereoEye.Right:					material.DisableKeyword(Keyword_ForceEyeNone);					material.DisableKeyword(Keyword_ForceEyeLeft);					material.EnableKeyword(Keyword_ForceEyeRight);					break;			}		}		public static void SetupStereoMaterial(Material material, StereoPacking packing)		{			switch (packing)			{				case StereoPacking.None:					material.DisableKeyword(Keyword_StereoTopBottom);					material.DisableKeyword(Keyword_StereoLeftRight);					material.DisableKeyword(Keyword_StereoCustomUV);					material.DisableKeyword(Keyword_StereoTwoTextures);					material.EnableKeyword(Keyword_StereoNone);					break;				case StereoPacking.TopBottom:					material.DisableKeyword(Keyword_StereoNone);					material.DisableKeyword(Keyword_StereoLeftRight);					material.DisableKeyword(Keyword_StereoCustomUV);					material.DisableKeyword(Keyword_StereoTwoTextures);					material.EnableKeyword(Keyword_StereoTopBottom);					break;				case StereoPacking.LeftRight:					material.DisableKeyword(Keyword_StereoNone);					material.DisableKeyword(Keyword_StereoTopBottom);					material.DisableKeyword(Keyword_StereoTwoTextures);					material.DisableKeyword(Keyword_StereoCustomUV);					material.EnableKeyword(Keyword_StereoLeftRight);					break;				case StereoPacking.CustomUV:					material.DisableKeyword(Keyword_StereoNone);					material.DisableKeyword(Keyword_StereoTopBottom);					material.DisableKeyword(Keyword_StereoLeftRight);					material.DisableKeyword(Keyword_StereoTwoTextures);					material.EnableKeyword(Keyword_StereoCustomUV);					break;				case StereoPacking.TwoTextures:					material.DisableKeyword(Keyword_StereoNone);					material.DisableKeyword(Keyword_StereoTopBottom);					material.DisableKeyword(Keyword_StereoLeftRight);					material.DisableKeyword(Keyword_StereoCustomUV);					material.EnableKeyword(Keyword_StereoTwoTextures);					break;			}		}		public static void SetupGlobalDebugStereoTinting(bool enabled)		{			if (enabled)			{				Shader.EnableKeyword(Keyword_StereoDebug);			}			else			{				Shader.DisableKeyword(Keyword_StereoDebug);			}		}		public static void SetupAlphaPackedMaterial(Material material, AlphaPacking packing)		{			switch (packing)			{				case AlphaPacking.None:					material.DisableKeyword(Keyword_AlphaPackTopBottom);					material.DisableKeyword(Keyword_AlphaPackLeftRight);					material.EnableKeyword(Keyword_AlphaPackNone);					break;				case AlphaPacking.TopBottom:					material.DisableKeyword(Keyword_AlphaPackNone);					material.DisableKeyword(Keyword_AlphaPackLeftRight);					material.EnableKeyword(Keyword_AlphaPackTopBottom);					break;				case AlphaPacking.LeftRight:					material.DisableKeyword(Keyword_AlphaPackNone);					material.DisableKeyword(Keyword_AlphaPackTopBottom);					material.EnableKeyword(Keyword_AlphaPackLeftRight);					break;			}		}		public static void SetupGammaMaterial(Material material, bool playerSupportsLinear)		{#if UNITY_PLATFORM_SUPPORTS_LINEAR			if (QualitySettings.activeColorSpace == ColorSpace.Linear && !playerSupportsLinear)			{				material.EnableKeyword(Keyword_ApplyGamma);			}			else			{				material.DisableKeyword(Keyword_ApplyGamma);			}#endif		}		public static void SetupTextureMatrix(Material material, float[] transform)		{			if (material == null)				return;			if (transform == null || transform.Length != 6)				transform = new float[6] { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };			Vector4 v0 = new Vector4(transform[0], transform[1], 0, 0);			Vector4 v1 = new Vector4(transform[2], transform[3], 0, 0);			Vector4 v2 = new Vector4(0, 0, 1, 0);			Vector4 v3 = new Vector4(transform[4], transform[5], 0, 1);			material.SetMatrix(PropTextureMatrix.Id, new Matrix4x4(v0, v1, v2, v3));		}		public static void SetupTextureMatrix(Material material, Matrix4x4 transform)		{			if (material == null)				return;			material.SetMatrix(PropTextureMatrix.Id, transform);		}#if UNITY_PLATFORM_SUPPORTS_YPCBCR		public static void SetupYpCbCrMaterial(Material material, bool enable, Matrix4x4 transform, Texture texture)		{			if (material.HasProperty(VideoRender.PropUseYpCbCr.Id))			{				if (enable)				{					material.EnableKeyword(VideoRender.Keyword_UseYpCbCr);					material.SetMatrix(VideoRender.PropYpCbCrTransform.Id, transform);					material.SetTexture(VideoRender.PropChromaTex.Id, texture);				}				else				{					material.DisableKeyword(VideoRender.Keyword_UseYpCbCr);				}			}		}#endif		public static void SetupVerticalFlipMaterial(Material material, bool flip)		{			material.SetFloat(VideoRender.PropVertScale.Id, flip?-1f:1f);		}		public static Texture GetTexture(MediaPlayer mediaPlayer, int textureIndex)		{			Texture result = null;			if (mediaPlayer != null)			{				if (mediaPlayer.UseResampler && mediaPlayer.FrameResampler != null && mediaPlayer.FrameResampler.OutputTexture != null)				{					if ( mediaPlayer.FrameResampler.OutputTexture.Length > textureIndex)					{						result = mediaPlayer.FrameResampler.OutputTexture[textureIndex];					}				}				else if (mediaPlayer.TextureProducer != null)				{					if (mediaPlayer.TextureProducer.GetTextureCount() > textureIndex)					{						result = mediaPlayer.TextureProducer.GetTexture(textureIndex);					}				}			}			return result;		}		public static void SetupMaterialForMedia(Material material, MediaPlayer mediaPlayer, int texturePropId = -1, Texture fallbackTexture = null, bool forceFallbackTexture = false)		{			Debug.Assert(material != null);			if (mediaPlayer != null)			{				Texture mainTexture = GetTexture(mediaPlayer, 0);				Matrix4x4 textureTransform = Matrix4x4.identity;				Texture yCbCrTexture = GetTexture(mediaPlayer, 1);				Matrix4x4 yCbCrTransform = Matrix4x4.identity;				StereoPacking stereoPacking = StereoPacking.None;				AlphaPacking alphaPacking = AlphaPacking.None;				bool flipY = false;				bool isLinear = false;				if (texturePropId != -1)				{					if (mainTexture == null || forceFallbackTexture)					{						mainTexture = fallbackTexture;					}					material.SetTexture(texturePropId, mainTexture);				}				ITextureProducer textureProducer = mediaPlayer.TextureProducer;				if (textureProducer != null)				{					flipY = textureProducer.RequiresVerticalFlip();					yCbCrTransform = textureProducer.GetYpCbCrTransform();					stereoPacking = textureProducer.GetTextureStereoPacking();					alphaPacking = textureProducer.GetTextureAlphaPacking();					textureTransform = textureProducer.GetTextureMatrix();				}				if (mediaPlayer.Info != null)				{					isLinear = mediaPlayer.Info.PlayerSupportsLinearColorSpace();				}				SetupMaterial(material, flipY, isLinear, yCbCrTransform, yCbCrTexture, textureTransform, mediaPlayer.VideoLayoutMapping, stereoPacking, alphaPacking);			}			else			{				if (texturePropId != -1)				{					material.SetTexture(texturePropId, fallbackTexture);				}				SetupMaterial(material, false, true, Matrix4x4.identity, null, Matrix4x4.identity);			}		}		internal static void SetupMaterial(			Material material,			bool flipVertically,			bool playerSupportsLinear,			Matrix4x4 ycbcrTransform,			Texture ycbcrTexture,			Matrix4x4 textureTransform,			VideoMapping mapping = VideoMapping.Normal,			StereoPacking stereoPacking = StereoPacking.None,			AlphaPacking alphaPacking = AlphaPacking.None)		{			SetupVerticalFlipMaterial(material, flipVertically);			// Apply changes for layout			if (material.HasProperty(VideoRender.PropLayout.Id))			{				VideoRender.SetupLayoutMaterial(material, mapping);			}			// Apply changes for stereo videos			if (material.HasProperty(VideoRender.PropStereo.Id))			{				VideoRender.SetupStereoMaterial(material, stereoPacking);			}			// Apply changes for alpha videos			if (material.HasProperty(VideoRender.PropAlphaPack.Id))			{				VideoRender.SetupAlphaPackedMaterial(material, alphaPacking);			}			// Apply gamma correction#if UNITY_PLATFORM_SUPPORTS_LINEAR			if (material.HasProperty(VideoRender.PropApplyGamma.Id))			{				VideoRender.SetupGammaMaterial(material, playerSupportsLinear);			}#endif			// Adjust for cropping/orientation (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			VideoRender.SetupTextureMatrix(material, textureTransform);#if UNITY_PLATFORM_SUPPORTS_YPCBCR			VideoRender.SetupYpCbCrMaterial(material, ycbcrTexture != null, ycbcrTransform, ycbcrTexture);#endif		}		[System.Flags]		public enum ResolveFlags : int		{			Mipmaps			= 1 << 0,			PackedAlpha		= 1 << 1,			StereoLeft		= 1 << 2,			StereoRight		= 1 << 3,			ColorspaceSRGB	= 1 << 4,		}		public static void SetupResolveMaterial(Material material, VideoResolveOptions options)		{			if (options.IsColourAdjust())			{				material.EnableKeyword(VideoRender.Keyword_UseHSBC);				material.SetFloat(VideoRender.PropHue.Id, options.hue);				material.SetFloat(VideoRender.PropSaturation.Id, options.saturation);				material.SetFloat(VideoRender.PropBrightness.Id, options.brightness);				material.SetFloat(VideoRender.PropContrast.Id, options.contrast);				material.SetFloat(VideoRender.PropInvGamma.Id, 1f / options.gamma);			}			else			{				material.DisableKeyword(VideoRender.Keyword_UseHSBC);			}			material.color = options.tint;		}		public static RenderTexture ResolveVideoToRenderTexture(Material resolveMaterial, RenderTexture targetTexture, ITextureProducer texture, ResolveFlags flags, ScaleMode scaleMode = ScaleMode.StretchToFill)		{			int targetWidth = texture.GetTexture(0).width;			int targetHeight = texture.GetTexture(0).height;			StereoEye eyeMode = StereoEye.Both;			if (((flags & ResolveFlags.StereoLeft) == ResolveFlags.StereoLeft) &&				((flags & ResolveFlags.StereoRight) != ResolveFlags.StereoRight))			{				eyeMode = StereoEye.Left;			}			else if (((flags & ResolveFlags.StereoLeft) != ResolveFlags.StereoLeft) &&					 ((flags & ResolveFlags.StereoRight) == ResolveFlags.StereoRight))			{				eyeMode = StereoEye.Right;			}			// RJT NOTE: No longer passing in PAR as combined with larger videos (e.g. 8K+) it can lead to textures >16K which most platforms don't support			// - Instead, the PAR is accounted for during drawing (which is more efficient too)			// - https://github.com/RenderHeads/UnityPlugin-AVProVideo/issues/1297			float pixelAspectRatio = 1.0f; // texture.GetTexturePixelAspectRatio();			GetResolveTextureSize(				texture.GetTextureAlphaPacking(),				texture.GetTextureStereoPacking(),				eyeMode,				pixelAspectRatio,				texture.GetTextureMatrix(),				ref targetWidth,				ref targetHeight);			if (targetTexture)			{				bool sizeChanged = (targetTexture.width != targetWidth) || (targetTexture.height != targetHeight);				if (sizeChanged)				{					RenderTexture.ReleaseTemporary(targetTexture);					targetTexture = null;				}			}			if (!targetTexture)			{				RenderTextureReadWrite readWrite = ((flags & ResolveFlags.ColorspaceSRGB) == ResolveFlags.ColorspaceSRGB) ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear;				targetTexture = RenderTexture.GetTemporary(targetWidth, targetHeight, 0, RenderTextureFormat.ARGB32, readWrite);			}			// Set target mipmap generation support			{				bool requiresMipmap = (flags & ResolveFlags.Mipmaps) == ResolveFlags.Mipmaps;				bool requiresRecreate = (targetTexture.IsCreated() && targetTexture.useMipMap != requiresMipmap);				if (requiresRecreate)				{					targetTexture.Release();				}				if (!targetTexture.IsCreated())				{					targetTexture.useMipMap = targetTexture.autoGenerateMips = requiresMipmap;					targetTexture.Create();				}			}			// Render resolve blit			// TODO: combine these two paths into a single material blit			{				bool prevSRGB = GL.sRGBWrite;				GL.sRGBWrite = targetTexture.sRGB;				RenderTexture prev = RenderTexture.active;				if (scaleMode == ScaleMode.StretchToFill)				{					Graphics.Blit(texture.GetTexture(0), targetTexture, resolveMaterial);				}				else				{					RenderTexture.active = targetTexture;					bool partialAreaRender = (scaleMode == ScaleMode.ScaleToFit);					if (partialAreaRender)					{						GL.Clear(false, true, Color.black);					}					VideoRender.DrawTexture(new Rect(0f, 0f, targetTexture.width, targetTexture.height), texture.GetTexture(0), scaleMode, texture.GetTextureAlphaPacking(), texture.GetTexturePixelAspectRatio(), resolveMaterial);				}				RenderTexture.active = prev;				GL.sRGBWrite = prevSRGB;			}			return targetTexture;		}		public static void GetResolveTextureSize(AlphaPacking alphaPacking, StereoPacking stereoPacking, StereoEye eyeMode, float pixelAspectRatio, Matrix4x4 textureXfrm, ref int width, ref int height)		{			Vector4 size = new Vector4(width, height, 0, 0);			size = textureXfrm * size;			width = (int)Mathf.Abs(size.x);			height = (int)Mathf.Abs(size.y);			switch (alphaPacking)			{				case AlphaPacking.LeftRight:					width /= 2;					break;				case AlphaPacking.TopBottom:					height /= 2;					break;			}			if (eyeMode != StereoEye.Both)			{				switch (stereoPacking)				{					case StereoPacking.LeftRight:						width /= 2;						break;					case StereoPacking.TopBottom:						height /= 2;						break;				}			}			if (pixelAspectRatio > 0f)			{				if (pixelAspectRatio > 1f)				{					width = Mathf.RoundToInt(width * pixelAspectRatio);				}				else if (pixelAspectRatio < 1f)				{					height = Mathf.RoundToInt(height / pixelAspectRatio);				}			}		}		public static bool RequiresResolve(ITextureProducer texture)		{			return (texture.GetTextureAlphaPacking() != AlphaPacking.None ||				texture.RequiresVerticalFlip() ||				texture.GetTextureStereoPacking() != StereoPacking.None ||				texture.GetTextureCount() > 1			);		}		public static void DrawTexture(Rect destRect, Texture texture, ScaleMode scaleMode, AlphaPacking alphaPacking, float pixelAspectRatio, Material material)		{			if (Event.current == null || Event.current.type == EventType.Repaint)			{				int sourceWidth = texture.width;				int sourceHeight = texture.height;				Matrix4x4 textureXfrm = Matrix4x4.identity;				GetResolveTextureSize(alphaPacking, StereoPacking.Unknown, StereoEye.Both, pixelAspectRatio, textureXfrm, ref sourceWidth, ref sourceHeight);				float sourceRatio = (float)sourceWidth / (float)sourceHeight;				Rect sourceRect = new Rect(0f, 0f, 1f, 1f);				switch (scaleMode)				{					case ScaleMode.ScaleAndCrop:						{							float destRatio = destRect.width / destRect.height;							if (destRatio > sourceRatio)							{								float adjust = sourceRatio / destRatio;								sourceRect = new Rect(0f, (1f - adjust) * 0.5f, 1f, adjust);							}							else							{								float adjust = destRatio / sourceRatio;								sourceRect = new Rect(0.5f - adjust * 0.5f, 0f, adjust, 1f);							}						}						break;					case ScaleMode.ScaleToFit:						{							float destRatio = destRect.width / destRect.height;							if (destRatio > sourceRatio)							{								float adjust = sourceRatio / destRatio;								destRect = new Rect(destRect.xMin + destRect.width * (1f - adjust) * 0.5f, destRect.yMin, adjust * destRect.width, destRect.height);							}							else							{								float adjust = destRatio / sourceRatio;								destRect = new Rect(destRect.xMin, destRect.yMin + destRect.height * (1f - adjust) * 0.5f, destRect.width, adjust * destRect.height);							}						}						break;					case ScaleMode.StretchToFill:						break;				}				GL.PushMatrix();				if (RenderTexture.active == null)				{					//GL.LoadPixelMatrix();					GL.LoadPixelMatrix(0f, Screen.width, Screen.height, 0f);				}				else				{					GL.LoadPixelMatrix(0f, RenderTexture.active.width, RenderTexture.active.height, 0f);				}				Graphics.DrawTexture(destRect, texture, sourceRect, 0, 0, 0, 0, GUI.color, material);				GL.PopMatrix();			}		}	}}
 |