first commit
This commit is contained in:
702
Assets/AVProVideo/Runtime/Scripts/Internal/Utils/VideoRender.cs
Normal file
702
Assets/AVProVideo/Runtime/Scripts/Internal/Utils/VideoRender.cs
Normal file
@@ -0,0 +1,702 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2025 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS
|
||||
#define UNITY_PLATFORM_SUPPORTS_YPCBCR
|
||||
#endif
|
||||
|
||||
#define UNITY_PLATFORM_SUPPORTS_LINEAR
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
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_TWO_TEXTURES";
|
||||
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");
|
||||
|
||||
// Default right-eye texture shader properties
|
||||
public static readonly LazyShaderProperty PropMainTex_R = new LazyShaderProperty("_MainTex_R");
|
||||
public static readonly LazyShaderProperty PropChromaTex_R = new LazyShaderProperty("_ChromaTex_R");
|
||||
|
||||
#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.Monoscopic:
|
||||
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.MultiviewLeftPrimary:
|
||||
case StereoPacking.MultiviewRightPrimary:
|
||||
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;
|
||||
|
||||
bool isUsingYCbCr = mediaPlayer.IsUsingYCbCr();
|
||||
|
||||
Texture yCbCrTexture = isUsingYCbCr ? GetTexture(mediaPlayer, 1) : null;
|
||||
Matrix4x4 yCbCrTransform = Matrix4x4.identity;
|
||||
|
||||
StereoPacking stereoPacking = StereoPacking.Monoscopic;
|
||||
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();
|
||||
if (isUsingYCbCr)
|
||||
{
|
||||
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);
|
||||
|
||||
if (stereoPacking == StereoPacking.MultiviewLeftPrimary || stereoPacking == StereoPacking.MultiviewRightPrimary)
|
||||
{
|
||||
#if UNITY_PLATFORM_SUPPORTS_YPCBCR
|
||||
if (isUsingYCbCr)
|
||||
{
|
||||
material.SetTexture(PropMainTex_R.Id, GetTexture(mediaPlayer, 2));
|
||||
material.SetTexture(PropChromaTex_R.Id, GetTexture(mediaPlayer, 3));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
material.SetTexture(PropMainTex_R.Id, GetTexture(mediaPlayer, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
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.Monoscopic,
|
||||
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)
|
||||
{
|
||||
GetCompatibleRenderTextureFormatOptions options = GetCompatibleRenderTextureFormatOptions.ForResolve;
|
||||
if (texture.GetTextureAlphaPacking() != AlphaPacking.None)
|
||||
{
|
||||
options |= GetCompatibleRenderTextureFormatOptions.RequiresAlpha;
|
||||
}
|
||||
RenderTextureFormat format = texture.GetCompatibleRenderTextureFormat(options);
|
||||
RenderTextureReadWrite readWrite = ((flags & ResolveFlags.ColorspaceSRGB) == ResolveFlags.ColorspaceSRGB) ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear;
|
||||
targetTexture = RenderTexture.GetTemporary(targetWidth, targetHeight, 0, format, 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.Monoscopic ||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user