Beispiel #1
0
    private void ConfigureEyeDesc(OVREye eye)
    {
        Vector2 texSize = Vector2.zero;
        Vector2 fovSize = Vector2.zero;

#if !UNITY_ANDROID || UNITY_EDITOR
        if (!OVRManager.instance.isVRPresent)
        {
            return;
        }

        OVRPlugin.Sizei    size    = OVRPlugin.GetEyeTextureSize((OVRPlugin.Eye)eye);
        OVRPlugin.Frustumf frustum = OVRPlugin.GetEyeFrustum((OVRPlugin.Eye)eye);

        texSize = new Vector2(size.w, size.h);
        fovSize = Mathf.Rad2Deg * new Vector2(frustum.fovX, frustum.fovY);
#else
        texSize = new Vector2(1024, 1024) * OVRManager.instance.nativeTextureScale;
        fovSize = new Vector2(90, 90);
#endif

        eyeDescs[(int)eye] = new EyeRenderDesc()
        {
            resolution = texSize,
            fov        = fovSize
        };
    }
Beispiel #2
0
 // Token: 0x060037EB RID: 14315 RVA: 0x0011D018 File Offset: 0x0011B418
 private void ConfigureEyeDesc(VRNode eye)
 {
     if (!OVRManager.isHmdPresent)
     {
         return;
     }
     OVRPlugin.Sizei    eyeTextureSize = OVRPlugin.GetEyeTextureSize((OVRPlugin.Eye)eye);
     OVRPlugin.Frustumf eyeFrustum     = OVRPlugin.GetEyeFrustum((OVRPlugin.Eye)eye);
     this.eyeDescs[(int)eye] = new OVRDisplay.EyeRenderDesc
     {
         resolution = new Vector2((float)eyeTextureSize.w, (float)eyeTextureSize.h),
         fov        = 57.29578f * new Vector2(eyeFrustum.fovX, eyeFrustum.fovY)
     };
 }
Beispiel #3
0
    private bool CreateLayerTextures(bool useMipmaps, OVRPlugin.Sizei size, bool isHdr)
    {
        bool result = false;

        if (this.stageCount <= 0)
        {
            return(false);
        }
        if (this.layerTextures == null)
        {
            this.frameIndex    = 0;
            this.layerTextures = new OVROverlay.LayerTexture[this.texturesPerStage];
        }
        for (int i = 0; i < this.texturesPerStage; i++)
        {
            if (this.layerTextures[i].swapChain == null)
            {
                this.layerTextures[i].swapChain = new Texture[this.stageCount];
            }
            if (this.layerTextures[i].swapChainPtr == null)
            {
                this.layerTextures[i].swapChainPtr = new IntPtr[this.stageCount];
            }
            for (int j = 0; j < this.stageCount; j++)
            {
                Texture texture = this.layerTextures[i].swapChain[j];
                IntPtr  intPtr  = this.layerTextures[i].swapChainPtr[j];
                if (!(texture != null) || !(intPtr != IntPtr.Zero))
                {
                    if (intPtr == IntPtr.Zero)
                    {
                        intPtr = OVRPlugin.GetLayerTexture(this.layerId, j, (OVRPlugin.Eye)i);
                    }
                    if (!(intPtr == IntPtr.Zero))
                    {
                        TextureFormat format = (!isHdr) ? TextureFormat.RGBA32 : TextureFormat.RGBAHalf;
                        if (this.currentOverlayShape != OVROverlay.OverlayShape.Cubemap && this.currentOverlayShape != OVROverlay.OverlayShape.OffcenterCubemap)
                        {
                            texture = Texture2D.CreateExternalTexture(size.w, size.h, format, useMipmaps, true, intPtr);
                        }
                        this.layerTextures[i].swapChain[j]    = texture;
                        this.layerTextures[i].swapChainPtr[j] = intPtr;
                        result = true;
                    }
                }
            }
        }
        return(result);
    }
    private void ConfigureEyeDesc(VR.VRNode eye)
    {
        if (!OVRManager.isHmdPresent)
        {
            return;
        }

        OVRPlugin.Sizei    size  = OVRPlugin.GetEyeTextureSize((OVRPlugin.Eye)eye);
        OVRPlugin.Frustumf frust = OVRPlugin.GetEyeFrustum((OVRPlugin.Eye)eye);

        eyeDescs[(int)eye] = new EyeRenderDesc()
        {
            resolution = new Vector2(size.w, size.h),
            fov        = Mathf.Rad2Deg * new Vector2(frust.fovX, frust.fovY),
        };
    }
Beispiel #5
0
    private bool PopulateLayer(int mipLevels, bool isHdr, OVRPlugin.Sizei size, int sampleCount)
    {
        bool result = false;
        RenderTextureFormat format = (!isHdr) ? RenderTextureFormat.ARGB32 : RenderTextureFormat.ARGBHalf;

        for (int i = 0; i < this.texturesPerStage; i++)
        {
            int     dstElement = (this.layout != OVRPlugin.LayerLayout.Array) ? 0 : i;
            int     num        = this.frameIndex % this.stageCount;
            Texture texture    = this.layerTextures[i].swapChain[num];
            if (!(texture == null))
            {
                for (int j = 0; j < mipLevels; j++)
                {
                    int num2 = size.w >> j;
                    if (num2 < 1)
                    {
                        num2 = 1;
                    }
                    int num3 = size.h >> j;
                    if (num3 < 1)
                    {
                        num3 = 1;
                    }
                    RenderTexture temporary = RenderTexture.GetTemporary(num2, num3, 0, format, RenderTextureReadWrite.Linear, sampleCount);
                    if (!temporary.IsCreated())
                    {
                        temporary.Create();
                    }
                    temporary.DiscardContents();
                    RenderTexture renderTexture = this.textures[i] as RenderTexture;
                    bool          flag          = isHdr || QualitySettings.activeColorSpace == ColorSpace.Linear;
                    flag |= (renderTexture != null && renderTexture.sRGB);
                    if (this.currentOverlayShape != OVROverlay.OverlayShape.Cubemap && this.currentOverlayShape != OVROverlay.OverlayShape.OffcenterCubemap)
                    {
                        OVROverlay.tex2DMaterial.SetInt("_linearToSrgb", (isHdr || !flag) ? 0 : 1);
                        OVROverlay.tex2DMaterial.SetInt("_premultiply", 1);
                        Graphics.Blit(this.textures[i], temporary, OVROverlay.tex2DMaterial);
                        Graphics.CopyTexture(temporary, 0, 0, texture, dstElement, j);
                    }
                    RenderTexture.ReleaseTemporary(temporary);
                    result = true;
                }
            }
        }
        return(result);
    }
Beispiel #6
0
    private void ConfigureEyeDesc(UnityEngine.VR.VRNode eye)
#endif
    {
        if (!OVRManager.isHmdPresent)
        {
            return;
        }

        OVRPlugin.Sizei size = OVRPlugin.GetEyeTextureSize((OVRPlugin.Eye)eye);

        eyeDescs[(int)eye]            = new EyeRenderDesc();
        eyeDescs[(int)eye].resolution = new Vector2(size.w, size.h);

        OVRPlugin.Frustumf2 frust;
        if (OVRPlugin.GetNodeFrustum2((OVRPlugin.Node)eye, out frust))
        {
            eyeDescs[(int)eye].fullFov.LeftFov  = Mathf.Rad2Deg * Mathf.Atan(frust.Fov.LeftTan);
            eyeDescs[(int)eye].fullFov.RightFov = Mathf.Rad2Deg * Mathf.Atan(frust.Fov.RightTan);
            eyeDescs[(int)eye].fullFov.UpFov    = Mathf.Rad2Deg * Mathf.Atan(frust.Fov.UpTan);
            eyeDescs[(int)eye].fullFov.DownFov  = Mathf.Rad2Deg * Mathf.Atan(frust.Fov.DownTan);
        }
        else
        {
            OVRPlugin.Frustumf frustOld = OVRPlugin.GetEyeFrustum((OVRPlugin.Eye)eye);
            eyeDescs[(int)eye].fullFov.LeftFov  = Mathf.Rad2Deg * frustOld.fovX * 0.5f;
            eyeDescs[(int)eye].fullFov.RightFov = Mathf.Rad2Deg * frustOld.fovX * 0.5f;
            eyeDescs[(int)eye].fullFov.UpFov    = Mathf.Rad2Deg * frustOld.fovY * 0.5f;
            eyeDescs[(int)eye].fullFov.DownFov  = Mathf.Rad2Deg * frustOld.fovY * 0.5f;
        }

        // Symmetric Fov uses the maximum fov angle
        float maxFovX = Mathf.Max(eyeDescs[(int)eye].fullFov.LeftFov, eyeDescs[(int)eye].fullFov.RightFov);
        float maxFovY = Mathf.Max(eyeDescs[(int)eye].fullFov.UpFov, eyeDescs[(int)eye].fullFov.DownFov);

        eyeDescs[(int)eye].fov.x = maxFovX * 2.0f;
        eyeDescs[(int)eye].fov.y = maxFovY * 2.0f;

        if (!OVRPlugin.AsymmetricFovEnabled)
        {
            eyeDescs[(int)eye].fullFov.LeftFov  = maxFovX;
            eyeDescs[(int)eye].fullFov.RightFov = maxFovX;

            eyeDescs[(int)eye].fullFov.UpFov   = maxFovY;
            eyeDescs[(int)eye].fullFov.DownFov = maxFovY;
        }
    }
Beispiel #7
0
    private bool PopulateLayer(int mipLevels, bool isHdr, OVRPlugin.Sizei size, int sampleCount, int stage)
    {
        if (isExternalSurface)
        {
            return(true);
        }

        bool ret = false;

        RenderTextureFormat rtFormat = (isHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;

        for (int eyeId = 0; eyeId < texturesPerStage; ++eyeId)
        {
            Texture et = layerTextures[eyeId].swapChain[stage];
            if (et == null)
            {
                continue;
            }

            for (int mip = 0; mip < mipLevels; ++mip)
            {
                int width = size.w >> mip;
                if (width < 1)
                {
                    width = 1;
                }
                int height = size.h >> mip;
                if (height < 1)
                {
                    height = 1;
                }
#if UNITY_2017_1_1 || UNITY_2017_2_OR_NEWER
                RenderTextureDescriptor descriptor = new RenderTextureDescriptor(width, height, rtFormat, 0);
                descriptor.msaaSamples      = sampleCount;
                descriptor.useMipMap        = true;
                descriptor.autoGenerateMips = false;
                descriptor.sRGB             = false;

                var tempRTDst = RenderTexture.GetTemporary(descriptor);
#else
                var tempRTDst = RenderTexture.GetTemporary(width, height, 0, rtFormat, RenderTextureReadWrite.Linear, sampleCount);
#endif

                if (!tempRTDst.IsCreated())
                {
                    tempRTDst.Create();
                }

                tempRTDst.DiscardContents();

                bool dataIsLinear = isHdr || (QualitySettings.activeColorSpace == ColorSpace.Linear);

#if !UNITY_2017_1_OR_NEWER
                var rt = textures[eyeId] as RenderTexture;
                dataIsLinear |= rt != null && rt.sRGB;                 //HACK: Unity 5.6 and earlier convert to linear on read from sRGB RenderTexture.
#endif
#if UNITY_ANDROID && !UNITY_EDITOR
                dataIsLinear = true;                 //HACK: Graphics.CopyTexture causes linear->srgb conversion on target write with D3D but not GLES.
#endif

                if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                {
                    tex2DMaterial.SetInt("_linearToSrgb", (!isHdr && dataIsLinear) ? 1 : 0);

                    //Resolve, decompress, swizzle, etc not handled by simple CopyTexture.
#if !UNITY_ANDROID || UNITY_EDITOR
                    // The PC compositor uses premultiplied alpha, so multiply it here.
                    tex2DMaterial.SetInt("_premultiply", 1);
#endif
                    Graphics.Blit(textures[eyeId], tempRTDst, tex2DMaterial);
                    Graphics.CopyTexture(tempRTDst, 0, 0, et, 0, mip);
                }
#if UNITY_2017_1_OR_NEWER
                else                 // Cubemap
                {
                    for (int face = 0; face < 6; ++face)
                    {
                        cubeMaterial.SetInt("_linearToSrgb", (!isHdr && dataIsLinear) ? 1 : 0);

#if !UNITY_ANDROID || UNITY_EDITOR
                        // The PC compositor uses premultiplied alpha, so multiply it here.
                        cubeMaterial.SetInt("_premultiply", 1);
#endif
                        cubeMaterial.SetInt("_face", face);
                        //Resolve, decompress, swizzle, etc not handled by simple CopyTexture.
                        Graphics.Blit(textures[eyeId], tempRTDst, cubeMaterial);
                        Graphics.CopyTexture(tempRTDst, 0, 0, et, face, mip);
                    }
                }
#endif
                RenderTexture.ReleaseTemporary(tempRTDst);

                ret = true;
            }
        }

        return(ret);
    }
Beispiel #8
0
    private OVRPlugin.LayerDesc GetCurrentLayerDesc()
    {
        OVRPlugin.Sizei textureSize = new OVRPlugin.Sizei()
        {
            w = 0, h = 0
        };

        if (isExternalSurface)
        {
            textureSize.w = externalSurfaceWidth;
            textureSize.h = externalSurfaceHeight;
        }
        else
        {
            if (textures[0] == null)
            {
                Debug.LogWarning("textures[0] hasn't been set");
            }
            textureSize.w = textures[0] ? textures[0].width : 0;
            textureSize.h = textures[0] ? textures[0].height : 0;
        }

        OVRPlugin.LayerDesc newDesc = new OVRPlugin.LayerDesc()
        {
            Format      = OVRPlugin.EyeTextureFormat.R8G8B8A8_sRGB,
            LayerFlags  = isExternalSurface ? 0 : (int)OVRPlugin.LayerFlags.TextureOriginAtBottomLeft,
            Layout      = layout,
            MipLevels   = 1,
            SampleCount = 1,
            Shape       = (OVRPlugin.OverlayShape)currentOverlayShape,
            TextureSize = textureSize
        };

        var tex2D = textures[0] as Texture2D;

        if (tex2D != null)
        {
            if (tex2D.format == TextureFormat.RGBAHalf || tex2D.format == TextureFormat.RGBAFloat)
            {
                newDesc.Format = OVRPlugin.EyeTextureFormat.R16G16B16A16_FP;
            }

            newDesc.MipLevels = tex2D.mipmapCount;
        }

        var texCube = textures[0] as Cubemap;

        if (texCube != null)
        {
            if (texCube.format == TextureFormat.RGBAHalf || texCube.format == TextureFormat.RGBAFloat)
            {
                newDesc.Format = OVRPlugin.EyeTextureFormat.R16G16B16A16_FP;
            }

            newDesc.MipLevels = texCube.mipmapCount;
        }

        var rt = textures[0] as RenderTexture;

        if (rt != null)
        {
            newDesc.SampleCount = rt.antiAliasing;

            if (rt.format == RenderTextureFormat.ARGBHalf || rt.format == RenderTextureFormat.ARGBFloat || rt.format == RenderTextureFormat.RGB111110Float)
            {
                newDesc.Format = OVRPlugin.EyeTextureFormat.R16G16B16A16_FP;
            }
        }

        if (isProtectedContent)
        {
            newDesc.LayerFlags |= (int)OVRPlugin.LayerFlags.ProtectedContent;
        }

        if (isExternalSurface)
        {
            newDesc.LayerFlags |= (int)OVRPlugin.LayerFlags.AndroidSurfaceSwapChain;
        }

        return(newDesc);
    }
Beispiel #9
0
    private bool CreateLayerTextures(bool useMipmaps, OVRPlugin.Sizei size, bool isHdr)
    {
        if (isExternalSurface)
        {
            if (externalSurfaceObject == System.IntPtr.Zero)
            {
                externalSurfaceObject = OVRPlugin.GetLayerAndroidSurfaceObject(layerId);
                if (externalSurfaceObject != System.IntPtr.Zero)
                {
                    Debug.LogFormat("GetLayerAndroidSurfaceObject returns {0}", externalSurfaceObject);
                    if (externalSurfaceObjectCreated != null)
                    {
                        externalSurfaceObjectCreated();
                    }
                }
            }
            return(false);
        }

        bool needsCopy = false;

        if (stageCount <= 0)
        {
            return(false);
        }

        // For newer SDKs, blit directly to the surface that will be used in compositing.

        if (layerTextures == null)
        {
            layerTextures = new LayerTexture[texturesPerStage];
        }

        for (int eyeId = 0; eyeId < texturesPerStage; ++eyeId)
        {
            if (layerTextures[eyeId].swapChain == null)
            {
                layerTextures[eyeId].swapChain = new Texture[stageCount];
            }

            if (layerTextures[eyeId].swapChainPtr == null)
            {
                layerTextures[eyeId].swapChainPtr = new IntPtr[stageCount];
            }

            for (int stage = 0; stage < stageCount; ++stage)
            {
                Texture sc    = layerTextures[eyeId].swapChain[stage];
                IntPtr  scPtr = layerTextures[eyeId].swapChainPtr[stage];

                if (sc != null && scPtr != IntPtr.Zero && size.w == sc.width && size.h == sc.height)
                {
                    continue;
                }

                if (scPtr == IntPtr.Zero)
                {
                    scPtr = OVRPlugin.GetLayerTexture(layerId, stage, (OVRPlugin.Eye)eyeId);
                }

                if (scPtr == IntPtr.Zero)
                {
                    continue;
                }

                var txFormat = (isHdr) ? TextureFormat.RGBAHalf : TextureFormat.RGBA32;

                if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                {
                    sc = Texture2D.CreateExternalTexture(size.w, size.h, txFormat, useMipmaps, true, scPtr);
                }
#if UNITY_2017_1_OR_NEWER
                else
                {
                    sc = Cubemap.CreateExternalTexture(size.w, txFormat, useMipmaps, scPtr);
                }
#endif

                layerTextures[eyeId].swapChain[stage]    = sc;
                layerTextures[eyeId].swapChainPtr[stage] = scPtr;

                needsCopy = true;
            }
        }

        return(needsCopy);
    }
Beispiel #10
0
    private bool CreateLayer(int mipLevels, int sampleCount, OVRPlugin.EyeTextureFormat etFormat, int flags, OVRPlugin.Sizei size, OVRPlugin.OverlayShape shape)
    {
        if (!layerIdHandle.IsAllocated || layerIdPtr == IntPtr.Zero)
        {
            layerIdHandle = GCHandle.Alloc(layerId, GCHandleType.Pinned);
            layerIdPtr    = layerIdHandle.AddrOfPinnedObject();
        }

        if (layerIndex == -1)
        {
            for (int i = 0; i < maxInstances; ++i)
            {
                if (instances[i] == null || instances[i] == this)
                {
                    layerIndex   = i;
                    instances[i] = this;
                    break;
                }
            }
        }

        bool needsSetup = (
            isOverridePending ||
            layerDesc.MipLevels != mipLevels ||
            layerDesc.SampleCount != sampleCount ||
            layerDesc.Format != etFormat ||
            layerDesc.Layout != layout ||
            layerDesc.LayerFlags != flags ||
            !layerDesc.TextureSize.Equals(size) ||
            layerDesc.Shape != shape);

        if (!needsSetup)
        {
            return(false);
        }

        OVRPlugin.LayerDesc desc = OVRPlugin.CalculateLayerDesc(shape, layout, size, mipLevels, sampleCount, etFormat, flags);
        OVRPlugin.EnqueueSetupLayer(desc, compositionDepth, layerIdPtr);
        layerId = (int)layerIdHandle.Target;

        if (layerId > 0)
        {
            layerDesc = desc;
            if (isExternalSurface)
            {
                stageCount = 1;
            }
            else
            {
                stageCount = OVRPlugin.GetLayerTextureStageCount(layerId);
            }
        }

        isOverridePending = false;

        return(true);
    }
Beispiel #11
0
 private bool CreateLayer(int mipLevels, int sampleCount, OVRPlugin.EyeTextureFormat etFormat, int flags, OVRPlugin.Sizei size, OVRPlugin.OverlayShape shape)
 {
     if (!this.layerIdHandle.IsAllocated || this.layerIdPtr == IntPtr.Zero)
     {
         this.layerIdHandle = GCHandle.Alloc(this.layerId, GCHandleType.Pinned);
         this.layerIdPtr    = this.layerIdHandle.AddrOfPinnedObject();
     }
     if (this.layerIndex == -1)
     {
         for (int i = 0; i < 15; i++)
         {
             if (OVROverlay.instances[i] == null || OVROverlay.instances[i] == this)
             {
                 this.layerIndex         = i;
                 OVROverlay.instances[i] = this;
                 break;
             }
         }
     }
     if (!this.isOverridePending && this.layerDesc.MipLevels == mipLevels && this.layerDesc.SampleCount == sampleCount && this.layerDesc.Format == etFormat && this.layerDesc.LayerFlags == flags && this.layerDesc.TextureSize.Equals(size) && this.layerDesc.Shape == shape)
     {
         return(false);
     }
     OVRPlugin.LayerDesc desc = OVRPlugin.CalculateLayerDesc(shape, this.layout, size, mipLevels, sampleCount, etFormat, flags);
     OVRPlugin.EnqueueSetupLayer(desc, this.layerIdPtr);
     this.layerId = (int)this.layerIdHandle.Target;
     if (this.layerId > 0)
     {
         this.layerDesc  = desc;
         this.stageCount = OVRPlugin.GetLayerTextureStageCount(this.layerId);
     }
     this.isOverridePending = false;
     return(true);
 }
    void Awake()
    {
        Debug.Log("Overlay Awake");

        if (premultiplyMaterial == null)
        {
            premultiplyMaterial = new Material(Shader.Find("Oculus/Alpha Premultiply"));
        }

        rend = GetComponent <Renderer>();

        if (textures.Length == 0)
        {
            textures = new Texture[] { null }
        }
        ;

        // Backward compatibility
        if (rend != null && textures[0] == null)
        {
            textures[0] = rend.material.mainTexture;
        }

        if (textures[0] != null)
        {
            cachedTextures[0] = textures[0];
            texNativePtrs[0]  = textures[0].GetNativeTexturePtr();
        }

#if UNITY_ANDROID && !UNITY_EDITOR
        if (textures.Length == 2 && textures[1] != null)
        {
            layout = (isMultiviewEnabled) ? OVRPlugin.LayerLayout.Array : OVRPlugin.LayerLayout.Stereo;
        }
        texturesPerStage = (layout == OVRPlugin.LayerLayout.Stereo) ? 2 : 1;
#endif
    }

    void OnEnable()
    {
        if (!OVRManager.isHmdPresent)
        {
            enabled = false;
            return;
        }

        OnDisable();

        for (int i = 0; i < maxInstances; ++i)
        {
            if (instances[i] == null || instances[i] == this)
            {
                layerIndex   = i;
                instances[i] = this;
                break;
            }
        }

        layerIdHandle = GCHandle.Alloc(layerId, GCHandleType.Pinned);
        layerIdPtr    = layerIdHandle.AddrOfPinnedObject();
    }

    void OnDisable()
    {
        if (layerIndex != -1)
        {
            // Turn off the overlay if it was on.
            OVRPlugin.EnqueueSubmitLayer(true, false, IntPtr.Zero, IntPtr.Zero, -1, 0, OVRPose.identity.ToPosef(), Vector3.one.ToVector3f(), layerIndex, (OVRPlugin.OverlayShape)_prevOverlayShape);
            instances[layerIndex] = null;
        }

        if (layerIdPtr != IntPtr.Zero)
        {
            OVRPlugin.EnqueueDestroyLayer(layerIdPtr);
            layerIdPtr = IntPtr.Zero;
            layerIdHandle.Free();
        }

        layerIndex = -1;
    }

    int prevFrameIndex = -1;

    void OnRenderObject()
    {
        // The overlay must be specified every eye frame, because it is positioned relative to the
        // current head location.  If frames are dropped, it will be time warped appropriately,
        // just like the eye buffers.
        if (!Camera.current.CompareTag("MainCamera") || Camera.current.cameraType != CameraType.Game || layerIndex == -1 || currentOverlayType == OverlayType.None || textures.Length < texturesPerStage)
        {
            return;
        }


        // Don't submit the same frame twice.
        if (Time.frameCount <= prevFrameIndex)
        {
            return;
        }
        prevFrameIndex = Time.frameCount;

#if !UNITY_ANDROID || UNITY_EDITOR
        if (currentOverlayShape == OverlayShape.OffcenterCubemap)
        {
            Debug.LogWarning("Overlay shape " + currentOverlayShape + " is not supported on current platform");
        }
#endif

        for (int i = 0; i < texturesPerStage; ++i)
        {
            if (textures[i] != cachedTextures[i])
            {
                cachedTextures[i] = textures[i];
                if (cachedTextures[i] != null)
                {
                    texNativePtrs[i] = cachedTextures[i].GetNativeTexturePtr();
                }
            }

            if (currentOverlayShape == OverlayShape.Cubemap)
            {
                if (textures[i] != null && textures[i].GetType() != typeof(Cubemap))
                {
                    Debug.LogError("Need Cubemap texture for cube map overlay");
                    return;
                }
            }
        }

        if (cachedTextures[0] == null || texNativePtrs[0] == IntPtr.Zero)
        {
            return;
        }

        bool overlay    = (currentOverlayType == OverlayType.Overlay);
        bool headLocked = false;
        for (var t = transform; t != null && !headLocked; t = t.parent)
        {
            headLocked |= (t == Camera.current.transform);
        }

        OVRPose pose  = (headLocked) ? transform.ToHeadSpacePose() : transform.ToTrackingSpacePose();
        Vector3 scale = transform.lossyScale;
        for (int i = 0; i < 3; ++i)
        {
            scale[i] /= Camera.current.transform.lossyScale[i];
        }
#if !UNITY_ANDROID
        if (currentOverlayShape == OverlayShape.Cubemap)
        {
            pose.position = Camera.current.transform.position;
        }
#endif
        // Pack the offsetCenter directly into pose.position for offcenterCubemap
        if (currentOverlayShape == OverlayShape.OffcenterCubemap)
        {
            pose.position = transform.position;
            if (pose.position.magnitude > 1.0f)
            {
                Debug.LogWarning("your cube map center offset's magnitude is greater than 1, which will cause some cube map pixel always invisible .");
            }
        }
        // Cylinder overlay sanity checking
        if (currentOverlayShape == OverlayShape.Cylinder)
        {
            float arcAngle = scale.x / scale.z / (float)Math.PI * 180.0f;
            if (arcAngle > 180.0f)
            {
                Debug.LogError("Cylinder overlay's arc angle has to be below 180 degree, current arc angle is " + arcAngle + " degree.");
                return;
            }
        }

        OVRPlugin.Sizei size = new OVRPlugin.Sizei()
        {
            w = textures[0].width, h = textures[0].height
        };
        int           flags                 = (int)OVRPlugin.LayerFlags.TextureOriginAtBottomLeft;
        int           mipLevels             = 1;
        int           sampleCount           = 1;
        TextureFormat txFormat              = TextureFormat.BGRA32;
        OVRPlugin.EyeTextureFormat etFormat = OVRPlugin.EyeTextureFormat.B8G8R8A8_sRGB;
        RenderTextureFormat        rtFormat = RenderTextureFormat.BGRA32;

        var tex2D = textures[0] as Texture2D;
        if (tex2D != null)
        {
            if (tex2D.format == TextureFormat.RGBAHalf || tex2D.format == TextureFormat.RGBAFloat)
            {
                txFormat = TextureFormat.RGBAHalf;
                etFormat = OVRPlugin.EyeTextureFormat.R16G16B16A16_FP;
                rtFormat = RenderTextureFormat.ARGBHalf;
            }
        }

        var rt = textures[0] as RenderTexture;
        if (rt != null)
        {
            sampleCount = rt.antiAliasing;

            if (rt.format == RenderTextureFormat.ARGBHalf)
            {
                txFormat = TextureFormat.RGBAHalf;
                etFormat = OVRPlugin.EyeTextureFormat.R16G16B16A16_FP;
                rtFormat = RenderTextureFormat.ARGBHalf;
            }
        }

        bool needsSetup = (
            !layerDesc.TextureSize.Equals(size) ||
            layerDesc.SampleCount != sampleCount ||
            layerDesc.LayerFlags != flags ||
            layerDesc.Shape != (OVRPlugin.OverlayShape)currentOverlayShape ||
            layerDesc.Layout != layout ||
            layerDesc.Format != etFormat);

        OVRPlugin.LayerDesc desc = new OVRPlugin.LayerDesc();

        if (layerIdPtr != IntPtr.Zero && needsSetup)
        {
            if ((int)layerIdHandle.Target != 0)
            {
                OVRPlugin.EnqueueDestroyLayer(layerIdPtr);
            }

            desc = OVRPlugin.CalculateLayerDesc((OVRPlugin.OverlayShape)currentOverlayShape, layout, size, mipLevels, sampleCount, etFormat, flags);
            OVRPlugin.EnqueueSetupLayer(desc, layerIdPtr);
            layerId = (int)layerIdHandle.Target;

            if (layerId > 0)
            {
                layerDesc = desc;
            }
        }

        if (layerId > 0)
        {
            // For newer SDKs, blit directly to the surface that will be used in compositing.

            int stageCount = OVRPlugin.GetLayerTextureStageCount(layerId);

            if (externalTextures == null)
            {
                frameIndex       = 0;
                externalTextures = new Texture[texturesPerStage][];
            }

            for (int eyeId = 0; eyeId < texturesPerStage; ++eyeId)
            {
                if (externalTextures[eyeId] == null)
                {
                    externalTextures[eyeId] = new Texture[stageCount];
                }

                int stage = frameIndex % stageCount;

                IntPtr externalTex = OVRPlugin.GetLayerTexture(layerId, stage, (OVRPlugin.Eye)eyeId);

                if (externalTex == IntPtr.Zero)
                {
                    continue;
                }

                bool needsCopy = isDynamic;

                Texture et = externalTextures[eyeId][stage];
                if (et == null)
                {
                    bool isSrgb = (etFormat == OVRPlugin.EyeTextureFormat.B8G8R8A8_sRGB || etFormat == OVRPlugin.EyeTextureFormat.R8G8B8A8_sRGB);

                    if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                    {
                        et = Texture2D.CreateExternalTexture(size.w, size.h, txFormat, mipLevels > 1, isSrgb, externalTex);
                    }
#if UNITY_2017_1_OR_NEWER
                    else
                    {
                        //et = Cubemap.CreateExternalTexture(size.w, size.h, txFormat, mipLevels > 1, isSrgb, externalTex);
                        et = Cubemap.CreateExternalTexture(size.w, txFormat, isSrgb, externalTex);
                    }
#endif

                    externalTextures[eyeId][stage] = et;
                    needsCopy = true;
                }

                if (needsCopy)
                {
                    // The compositor uses premultiplied alpha, so multiply it here.
                    if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                    {
                        var tempRT = RenderTexture.GetTemporary(size.w, size.h, 0, rtFormat, RenderTextureReadWrite.Default, sampleCount);
#if UNITY_ANDROID && !UNITY_EDITOR
                        Graphics.Blit(textures[eyeId], tempRT);                         //Resolve, decompress, swizzle, etc not handled by simple CopyTexture.
#else
                        Graphics.Blit(textures[eyeId], tempRT, premultiplyMaterial);
#endif
                        Graphics.CopyTexture(tempRT, 0, 0, et, 0, 0);
                        RenderTexture.ReleaseTemporary(tempRT);
                    }
#if UNITY_2017_1_OR_NEWER
                    else
                    {
                        var tempRTSrc = RenderTexture.GetTemporary(size.w, size.h, 0, rtFormat, RenderTextureReadWrite.Default, sampleCount);
                        var tempRTDst = RenderTexture.GetTemporary(size.w, size.h, 0, rtFormat, RenderTextureReadWrite.Default, sampleCount);

                        for (int face = 0; face < 6; ++face)
                        {
                            //HACK: It would be much more efficient to blit directly from textures[eyeId] to et, but Unity's API doesn't support that.
                            //Suggest using a native plugin to render directly to a cubemap layer for 360 video, etc.
                            Graphics.CopyTexture(textures[eyeId], face, 0, tempRTSrc, 0, 0);
                            Graphics.Blit(tempRTSrc, tempRTDst, premultiplyMaterial);
                            Graphics.CopyTexture(tempRTDst, 0, 0, et, face, 0);
                        }
                        RenderTexture.ReleaseTemporary(tempRTSrc);
                        RenderTexture.ReleaseTemporary(tempRTDst);
                    }
#endif
                }
            }

            bool isOverlayVisible = OVRPlugin.EnqueueSubmitLayer(overlay, headLocked, texNativePtrs[0], texNativePtrs[1], layerId, frameIndex, pose.flipZ().ToPosef(), scale.ToVector3f(), layerIndex, (OVRPlugin.OverlayShape)currentOverlayShape);
            if (isDynamic)
            {
                ++frameIndex;
            }
            _prevOverlayShape = currentOverlayShape;
            if (rend)
            {
                rend.enabled = !isOverlayVisible;
            }
        }
    }
}
Beispiel #13
0
    private bool PopulateLayer(int mipLevels, bool isHdr, OVRPlugin.Sizei size, int sampleCount, int stage)
    {
        if (isExternalSurface)
        {
            return(true);
        }

        bool ret = false;

        RenderTextureFormat rtFormat = (isHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;

        for (int eyeId = 0; eyeId < texturesPerStage; ++eyeId)
        {
            Texture et = layerTextures[eyeId].swapChain[stage];
            if (et == null)
            {
                continue;
            }

            for (int mip = 0; mip < mipLevels; ++mip)
            {
                bool dataIsLinear = isHdr || (QualitySettings.activeColorSpace == ColorSpace.Linear);

                var rt = textures[eyeId] as RenderTexture;
#if UNITY_ANDROID && !UNITY_EDITOR
                dataIsLinear = true;                 //HACK: Graphics.CopyTexture causes linear->srgb conversion on target write with D3D but not GLES.
#endif
                // PC requries premultiplied Alpha
                bool requiresPremultipliedAlpha = !Application.isMobilePlatform;

                bool linearToSRGB = !isHdr && dataIsLinear;
                // if the texture needs to be premultiplied, premultiply it unless its already premultiplied
                bool premultiplyAlpha = requiresPremultipliedAlpha && !isAlphaPremultiplied;

                bool bypassBlit = !linearToSRGB && !premultiplyAlpha && rt != null && rt.format == rtFormat;

                RenderTexture tempRTDst = null;

                if (!bypassBlit)
                {
                    int width = size.w >> mip;
                    if (width < 1)
                    {
                        width = 1;
                    }
                    int height = size.h >> mip;
                    if (height < 1)
                    {
                        height = 1;
                    }
                    RenderTextureDescriptor descriptor = new RenderTextureDescriptor(width, height, rtFormat, 0);
                    descriptor.msaaSamples      = sampleCount;
                    descriptor.useMipMap        = true;
                    descriptor.autoGenerateMips = false;
                    descriptor.sRGB             = false;

                    tempRTDst = RenderTexture.GetTemporary(descriptor);

                    if (!tempRTDst.IsCreated())
                    {
                        tempRTDst.Create();
                    }

                    tempRTDst.DiscardContents();

                    Material blitMat = null;
                    if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                    {
                        blitMat = tex2DMaterial;
                    }
                    else
                    {
                        blitMat = cubeMaterial;
                    }

                    blitMat.SetInt("_linearToSrgb", linearToSRGB ? 1 : 0);
                    blitMat.SetInt("_premultiply", premultiplyAlpha ? 1 : 0);
                }

                if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                {
                    if (bypassBlit)
                    {
                        Graphics.CopyTexture(textures[eyeId], 0, mip, et, 0, mip);
                    }
                    else
                    {
                        if (overrideTextureRectMatrix)
                        {
                            BlitSubImage(textures[eyeId], tempRTDst, tex2DMaterial, GetBlitRect(eyeId));
                        }
                        else
                        {
                            Graphics.Blit(textures[eyeId], tempRTDst, tex2DMaterial);
                        }
                        //Resolve, decompress, swizzle, etc not handled by simple CopyTexture.
                        Graphics.CopyTexture(tempRTDst, 0, 0, et, 0, mip);
                    }
                }
                else                 // Cubemap
                {
                    for (int face = 0; face < 6; ++face)
                    {
                        cubeMaterial.SetInt("_face", face);
                        if (bypassBlit)
                        {
                            Graphics.CopyTexture(textures[eyeId], face, mip, et, face, mip);
                        }
                        else
                        {
                            //Resolve, decompress, swizzle, etc not handled by simple CopyTexture.
                            Graphics.Blit(textures[eyeId], tempRTDst, cubeMaterial);
                            Graphics.CopyTexture(tempRTDst, 0, 0, et, face, mip);
                        }
                    }
                }
                if (tempRTDst != null)
                {
                    RenderTexture.ReleaseTemporary(tempRTDst);
                }

                ret = true;
            }
        }

        return(ret);
    }
Beispiel #14
0
    private bool PopulateLayer(int mipLevels, bool isHdr, OVRPlugin.Sizei size, int sampleCount)
    {
        bool ret = false;

        RenderTextureFormat rtFormat = (isHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;

        for (int eyeId = 0; eyeId < texturesPerStage; ++eyeId)
        {
            int dstElement = (layout == OVRPlugin.LayerLayout.Array) ? eyeId : 0;

            int     stage = frameIndex % stageCount;
            Texture et    = layerTextures[eyeId].swapChain[stage];
            if (et == null)
            {
                continue;
            }

            for (int mip = 0; mip < mipLevels; ++mip)
            {
#if UNITY_2017_1_1 || UNITY_2017_2_OR_NEWER
                int width = size.w >> mip;
                if (width < 1)
                {
                    width = 1;
                }
                int height = size.h >> mip;
                if (height < 1)
                {
                    height = 1;
                }

                RenderTextureDescriptor descriptor = new RenderTextureDescriptor(width, height, rtFormat, 0);
                descriptor.msaaSamples      = sampleCount;
                descriptor.useMipMap        = true;
                descriptor.autoGenerateMips = false;

                var tempRTDst = RenderTexture.GetTemporary(descriptor);
#else
                var tempRTDst = RenderTexture.GetTemporary(size.w >> mip, size.h >> mip, 0, rtFormat, RenderTextureReadWrite.Default, sampleCount);
#endif

                if (!tempRTDst.IsCreated())
                {
                    tempRTDst.Create();
                }

                tempRTDst.DiscardContents();

                if (currentOverlayShape != OverlayShape.Cubemap && currentOverlayShape != OverlayShape.OffcenterCubemap)
                {
#if UNITY_ANDROID && !UNITY_EDITOR
                    if (((textures[eyeId] as Cubemap) != null) &&
                        ((et as Cubemap) != null) &&
                        ((textures[eyeId] as Cubemap).format == (et as Cubemap).format))
                    {
                        Graphics.CopyTexture(textures[eyeId], 0, mip, et, 0, mip);
                    }
                    else
                    {
                        Graphics.Blit(textures[eyeId], tempRTDst);                         //Resolve, decompress, swizzle, etc not handled by simple CopyTexture.
                        Graphics.CopyTexture(tempRTDst, 0, 0, et, dstElement, mip);
                    }
#else
                    // The PC compositor uses premultiplied alpha, so multiply it here.
                    Graphics.Blit(textures[eyeId], tempRTDst, premultiplyMaterial);
                    Graphics.CopyTexture(tempRTDst, 0, 0, et, dstElement, mip);
#endif
                }
#if UNITY_2017_1_OR_NEWER
                else                 // Cubemap
                {
                    var tempRTSrc = RenderTexture.GetTemporary(size.w >> mip, size.h >> mip, 0, rtFormat, RenderTextureReadWrite.Default, sampleCount);

                    if (!tempRTSrc.IsCreated())
                    {
                        tempRTSrc.Create();
                    }

                    tempRTSrc.DiscardContents();

                    for (int face = 0; face < 6; ++face)
                    {
#if UNITY_ANDROID && !UNITY_EDITOR
                        if ((textures[eyeId] as Cubemap).format == (et as Cubemap).format)
                        {
                            Graphics.CopyTexture(textures[eyeId], face, mip, et, 0, mip);
                        }
                        else
                        {
                            //HACK: It would be much more efficient to blit directly from textures[eyeId] to et, but Unity's API doesn't support that.
                            //Suggest using a native plugin to render directly to a cubemap layer for 360 video, etc.
                            Graphics.CopyTexture(textures[eyeId], face, mip, tempRTSrc, 0, 0);
                            Graphics.Blit(tempRTSrc, tempRTDst);
                            Graphics.CopyTexture(tempRTDst, 0, 0, et, face, mip);
                        }
#else
                        //HACK: It would be much more efficient to blit directly from textures[eyeId] to et, but Unity's API doesn't support that.
                        //Suggest using a native plugin to render directly to a cubemap layer for 360 video, etc.
                        Graphics.CopyTexture(textures[eyeId], face, mip, tempRTSrc, 0, 0);
                        // The PC compositor uses premultiplied alpha, so multiply it here.
                        Graphics.Blit(tempRTSrc, tempRTDst, premultiplyMaterial);
                        Graphics.CopyTexture(tempRTDst, 0, 0, et, face, mip);
#endif
                    }
                    RenderTexture.ReleaseTemporary(tempRTSrc);
                }
#endif
                RenderTexture.ReleaseTemporary(tempRTDst);

                ret = true;
            }
        }

        return(ret);
    }