您的位置:首页 > 编程语言 > Go语言

Qualcomm_Snapdragon_VR_SDK SvrEye脚本简介(1)

2018-02-28 11:09 801 查看
从本文开始,介绍Unity版本的Qcom VR SDK中另一个比较重要的脚本SvrEye。
在之前的系列中讲到,SvrEye脚本是在程序运行后SvrManager动态添加到左右眼物体上的。具体SvrEye代码如下,后面章节中将具体介绍SvrEye中的属性和方法的作用。
public static List<SvrEye> Instances = new List<SvrEye>();

public enum eSide
{
Left = 1,
Right = 2,
Both = 3,
[HideInInspector]
Count = Both
};

public enum eType
{
RenderTexture = 0,
StandardTexture = 1,
EglTexture = 2,
};

public delegate void OnPostRenderCallback();
public OnPostRenderCallback OnPostRenderListener;

public delegate void OnPreRenderCallback();
public OnPreRenderCallback OnPreRenderListener;

[Tooltip("Layer depth stack")]
public int layerDepth = 0;
[Tooltip("Image display transform")]
public Camera imageCamera;
[Tooltip("Image type: 0/Camera render target, 1/Texture 2d, 2/External egl")]
public eType imageType = eType.RenderTexture;
[Tooltip("Image texture used when ImageType is StandardTexture")]
public Texture imageTexture;
[Tooltip("Image transform for scale, rotation and position (optional)")]
public Transform imageTransform;
[Tooltip("Image display region (camera clip space)")]
public Vector4 clipLowerLeft = new Vector4(-1, -1, 0, 1);
public Vector4 clipUpperLeft = new Vector4(-1, 1, 0, 1);
public Vector4 clipUpperRight = new Vector4(1, 1, 0, 1);
public Vector4 clipLowerRight = new Vector4(1, -1, 0, 1);
[Tooltip("Image source region (texture uv space)")]
public Vector2 uvLowerLeft = new Vector2(0, 0);
public Vector2 uvUpperLeft = new Vector2(0, 1);
public Vector2 uvUpperRight = new Vector2(1, 1);
public Vector2 uvLowerRight = new Vector2(1, 0);
[Tooltip("Render target scale factor")]
public float resolutionScaleFactor = 1.0f;
[Tooltip("Side mask")]
public eSide side = eSide.Both;

private float fovMargin = 0f;
private RenderTextureFormat format = RenderTextureFormat.Default;
private Vector2 resolution = new Vector2(1024.0f, 1024.0f);
private int antiAliasing = 1;
private int depth = 24;
private int frustumType = 0;
private const int bufferCount = 3;
private RenderTexture[] eyeTextures = new RenderTexture[bufferCount];
private int[] eyeTextureIds = new int[bufferCount];
private int currentTextureIndex = 0;
private Camera[] mainCameras = null;
private bool dirty = false;
private Coroutine recreateBuffersCoroutine = null;

public int CompareTo(SvrEye that)
{
return this.layerDepth.CompareTo(that.layerDepth);
}

public float FovMargin
{
get { return fovMargin; }
set { fovMargin = value; }
}

public int FrustumType
{
get { return frustumType; }
set { frustumType = value; }
}

public void SetImage(Texture2D texture)
{
imageTexture = texture;
InitializeBuffers();
}

public eType ImageType
{
get { return imageType; }
set { imageType = value; }
}

public eSide Side
{
get { return side; }
set { side = value; }
}

public RenderTextureFormat Format
{
get { return format; }
set { SetDirty(format != value); format = value; }
}

public int AntiAliasing
{
get { return antiAliasing; }
set { SetDirty(antiAliasing != value); antiAliasing = value; }
}

public int Depth
{
get { return depth; }
set { SetDirty(depth != value); depth = value; }
}

public Vector2 Resolution
{
get { return resolution; }
set { SetDirty(!Mathf.Approximately(resolution.x, value.x) || !Mathf.Approximately(resolution.y, value.y)); resolution = value; }
}

public float ResolutionScaleFactor
{
get { return resolutionScaleFactor; }
set { SetDirty(!Mathf.Approximately(resolutionScaleFactor, value)); resolutionScaleFactor = value; }
}

void SetDirty(bool value)
{
dirty = dirty == true ? true : value;
}

public int TextureId
{
get { return eyeTextureIds[currentTextureIndex]; }
set { eyeTextureIds[currentTextureIndex] = value; }
}
public Texture TexturePtr
{
get { return (imageTexture != null ? imageTexture : (Texture)eyeTextures[currentTextureIndex]); }
}

void Awake()
{
Instances.Add(this);
AcquireComponents();
InitializeCoords();
}

void OnDestroy()
{
Instances.Remove(this);
}

void AcquireComponents()
{
if (imageCamera == null) imageCamera = gameObject.GetComponent<Camera>();
Debug.Assert(imageCamera != null, "ImageCamera object required");
mainCameras = imageCamera.GetComponentsInChildren<Camera>();
}

void Start()
{
//Initialize(); Called by SvrManager.InitializeEyes()
}

void LateUpdate()
{
UpdateCoords();
}

public void Initialize()
{
InitializeBuffers();
InitializeCameras();
}

void InitializeBuffers()
{
for (int i = 0; i < bufferCount; ++i)
{
if (eyeTextures[i] != null)
eyeTextures[i].Release();
switch(imageType)
{
case eType.RenderTexture:
eyeTextures[i] = new RenderTexture((int)(resolution.x * resolutionScaleFactor), (int)(resolution.y * resolutionScaleFactor), depth, format);
eyeTextures[i].antiAliasing = antiAliasing;
eyeTextures[i].Create();
eyeTextureIds[i] = eyeTextures[i].GetNativeTexturePtr().ToInt32();
Debug.Log("Create Render Texture with ID: " + eyeTextureIds[i] + " Width: " + eyeTextures[i].width + " Height: " + eyeTextures[i].height + " AA: " + eyeTextures[i].antiAliasing);
break;

case eType.StandardTexture:
if (imageTexture) eyeTextureIds[i] = imageTexture.GetNativeTexturePtr().ToInt32();
break;

case eType.EglTexture:
eyeTextureIds[i] = 0;
break;
}
}
dirty = false;
}

void InitializeCameras()
{
...
}

void InitializeCoords()
{
...
}

void UpdateCoords()
{
if (imageTransform == null)
return;

var viewCamera = mainCameras[0];
if (viewCamera == null)
return;

var extents = 0.5f * Vector3.one;
var center = Vector3.zero;

var worldLowerLeft = new Vector4(center.x - extents.x, center.y - extents.y, 0, 1);
var worldUpperLeft = new Vector4(center.x - extents.x, center.y + extents.y, 0, 1);
var worldUpperRight = new Vector4(center.x + extents.x, center.y + extents.y, 0, 1);
var worldLowerRight = new Vector4(center.x + extents.x, center.y - extents.y, 0, 1);

Matrix4x4 MVP = viewCamera.projectionMatrix * viewCamera.worldToCameraMatrix * imageTransform.localToWorldMatrix;

clipLowerLeft = MVP * worldLowerLeft;
clipUpperLeft = MVP * worldUpperLeft;
clipUpperRight = MVP * worldUpperRight;
clipLowerRight = MVP * worldLowerRight;
}

void OnPreRender()
{
...
}

void SwapBuffers()
{
if (imageType != eType.RenderTexture) return;

currentTextureIndex = ++currentTextureIndex % bufferCount;
var targetTexture = eyeTextures[currentTextureIndex];
if (targetTexture == null) return;

for (int i = 0; i < mainCameras.Length; i++)
{
mainCameras[i].targetTexture = targetTexture;
}
targetTexture.DiscardContents();
}

void OnPostRender()
{
RecreateBuffersIfDirty();
if (OnPostRenderListener != null)
{
OnPostRenderListener();
}
}

void RecreateBuffersIfDirty()
{
if (dirty)
{
if (recreateBuffersCoroutine != null)
{
StopCoroutine(recreateBuffersCoroutine);
recreateBuffersCoroutine = null;
}

recreateBuffersCoroutine = StartCoroutine(RecreateBuffersDeferred());
dirty = false;
}
}

IEnumerator RecreateBuffersDeferred()
{
int i = 0;
while (i < bufferCount)
{
int index = currentTextureIndex - 1;
index = index >= 0 ? index : bufferCount - 1;

if (eyeTextures[index] != null)
eyeTextures[index].Release();

switch (imageType)
{
case eType.RenderTexture:
eyeTextures[index] = new RenderTexture((int)(resolution.x * resolutionScaleFactor), (int)(resolution.y * resolutionScaleFactor), depth, format);
eyeTextures[index].antiAliasing = antiAliasing;
eyeTextures[index].Create();
eyeTextureIds[index] = eyeTextures[index].GetNativeTexturePtr().ToInt32();
Debug.Log("Re-create Render Texture with ID: " + eyeTextureIds[index] + " Width: " + eyeTextures[index].width + " Height: " + eyeTextures[index].height + " AA: " + eyeTextures[index].antiAliasing);
break;

case eType.StandardTexture:
if (imageTexture) eyeTextureIds[index] = imageTexture.GetNativeTexturePtr().ToInt32();
break;

case eType.EglTexture:
eyeTextureIds[index] = 0;
break;
}

int prevTextureIndex = currentTextureIndex;
yield return new WaitUntil(() => currentTextureIndex != prevTextureIndex);

i++;
}

yield break;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: