Example #1
0
 private void OnDestroy()
 {
     if (varjoCamera != null && cameraBlitCB != null && blitCBInjected)
     {
         varjoCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffects, cameraBlitCB);
         blitCBInjected = false;
     }
     if (camRenderTextures != null)
     {
         foreach (var rt in camRenderTextures)
         {
             if (rt != null)
             {
                 rt.Release();
                 Destroy(rt);
             }
         }
     }
     if (camSwapchains != null)
     {
         if (VarjoPlugin.SessionValid)
         {
             foreach (var swapchain in camSwapchains)
             {
                 VarjoPlugin.QueueDestroySwapchain(swapchain);
             }
             VarjoManager.Instance.Plugin.IssuePluginEvent(VarjoPlugin.VARJO_RENDER_EVT_PROCESS_SWAPCHAINS);
         }
     }
 }
        private static bool CheckError()
        {
            int error = VarjoPlugin.GetError();

            if (error != 0)
            {
                Debug.LogWarning(VarjoPlugin.GetErrorMsg(error));
                return(false);
            }
            return(true);
        }
Example #3
0
        IEnumerator InitializeSession()
        {
            Plugin.AttemptSessionInit();

            // If we failed to initialize the session, attempt to initialize a valid session until we get one.
            if (!VarjoPlugin.SessionValid)
            {
                Debug.LogWarning("Failed to initialize a Varjo session. Entering into poll mode...");

                EnableAllViewportCameras(false);

                while (!VarjoPlugin.SessionValid)
                {
                    bool wait = true;
                    Plugin.AttemptSessionInitThreaded(() => wait = false);
                    while (wait)
                    {
                        yield return(new WaitForSecondsRealtime(0.5f));
                    }
                }

                EnableAllViewportCameras(true);
            }

            int viewCount = VarjoPlugin.GetViewCount();

            if (viewCount != 4)
            {
                Debug.LogErrorFormat("Only 4 views are supported by this plugin, however Varjo Runtime reports {0} views", viewCount);
                EnableAllViewportCameras(false);
                while (true)
                {
                    yield return(new WaitForSecondsRealtime(0.5f));
                }
            }

            Debug.Log("Varjo session init successful");

            StartCoroutine(EndFrameCoroutine());
        }
Example #4
0
        private new void Awake()
        {
            unityThread = Thread.CurrentThread;

            if (_instance == null)
            {
                _instance = this;
            }
            else
            {
                Debug.LogError("Multiple instances of VarjoManager. Destroying the new one.");
                Destroy(gameObject);
                return;
            }

            Plugin = new VarjoPlugin();

            VarjoSystemPresent = VarjoPlugin.IsVarjoSystemInstalled();
            if (!VarjoSystemPresent)
            {
                Debug.LogWarning("Varjo system not found.");
                return;
            }

            base.Awake();

            // Check that the varjoCamera is valid.
            if (varjoCamera == null)
            {
                varjoCamera = Camera.main;
                if (varjoCamera == null)
                {
                    LogWarning("No camera attached to VarjoManager. Attach a camera or make sure there is main camera in the scene.");
                    enabled = false;
                    return;
                }
            }

            StartCoroutine(InitializeSession());
        }
Example #5
0
        private bool VerifyCamera()
        {
            if (cam == null)
            {
                cam = GetComponent <Camera>();
            }
            if (cam == null)
            {
                cam = gameObject.AddComponent <Camera>();
            }
            if (m_Owner == null)
            {
                m_Owner = GetComponentInParent <VarjoLayer>();
            }

            if (cam && m_Owner && m_Owner.useOcclusionMesh && (m_OcclusionMeshVerts == null))
            {
                m_OcclusionMesh      = null;
                m_OcclusionMeshVerts = VarjoPlugin.GetOcclusionMesh((int)CameraId);

                if (m_OcclusionMeshVerts.Length > 0)
                {
                    m_OcclusionMesh = new Mesh();
                    int vertCount = m_OcclusionMeshVerts.Length / 2;
                    var vertices  = new Vector3[vertCount];
                    var indices   = new int[vertices.Length];
                    for (int i = 0; i < vertices.Length; ++i)
                    {
                        vertices[i] = new Vector3(m_OcclusionMeshVerts[i * 2], m_OcclusionMeshVerts[i * 2 + 1], 0.0f);
                        indices[i]  = i;
                    }

                    m_OcclusionMesh.vertices  = vertices;
                    m_OcclusionMesh.triangles = indices;
                }
            }

            return(cam != null);
        }
Example #6
0
        // Retrieve the occlusion mesh, store it as a triangle list into a float[], with alternating x and y coordinates
        public static float[] GetOcclusionMesh(int viewIndex)
        {
            int    vertCount = 0;
            IntPtr vertexData;
            var    occMesh = CreateOcclusionMesh((int)viewIndex, out vertCount, out vertexData);

            if (occMesh != (IntPtr)0)
            {
                var res = new float[vertCount * 2];
                if (vertCount > 0)
                {
                    System.Runtime.InteropServices.Marshal.Copy(vertexData, res, 0, vertCount * 2);
                }

                VarjoPlugin.FreeOcclusionMesh(occMesh);
                return(res);
            }
            else
            {
                return(new float[0]);
            }
        }
Example #7
0
        private IEnumerator EndFrameCoroutine()
        {
            while (true)
            {
                yield return(yieldEndOfFrame);

                if (!VarjoPlugin.SessionValid || !beginFrameCalled)
                {
                    Profiler.BeginSample("Varjo.EndOfFrame.ThrottleFor100ms");
                    // Sleep for 100ms so that we won't hog the CPU
                    Thread.Sleep(100);
                    // Still poll events if we have a session
                    if (VarjoPlugin.SessionValid)
                    {
                        Plugin.IssuePluginEvent(VarjoPlugin.VARJO_RENDER_EVT_POLL_EVENTS);
                    }
                    GL.Flush();
                    Profiler.EndSample();
                    continue;
                }

                Profiler.BeginSample("Varjo.EndOfFrame");

                if (VarjoManager.Instance.viewportCameras == null || VarjoManager.Instance.viewportCameras.Count != 4)
                {
                    VarjoManager.LogError("VarjoViewCombiner can't access a proper viewport array.");
                    continue;
                }

                GL.sRGBWrite = true;

                Profiler.BeginSample("Varjo.Submit");

                submission.Clear();
                // Sort the layers according to layer depth
                foreach (var varjoLayer in layers.OrderBy(l => l.layerOrder))
                {
                    if (varjoLayer.layerEnabled)
                    {
                        submission.Add(varjoLayer.PrepareForSubmission());
                    }
                }

                var subArray = submission.ToArray();
                VarjoPlugin.QueueSubmission(subArray.Length, subArray);

                Profiler.EndSample();

                // Blit to screen if SRPs are in use
                if (GraphicsSettings.renderPipelineAsset != null)
                {
                    Profiler.BeginSample("Varjo.BlitToScreen");
                    // Blit left context of the main layer to screen
                    if (flipY)
                    {
                        Graphics.Blit(GetRenderTextureForCamera(VarjoViewCamera.CAMERA_ID.CONTEXT_LEFT), (RenderTexture)null, new Vector2(contextDisplayFactor, contextDisplayFactor), new Vector2(0.0f, 1.0f - contextDisplayFactor));
                    }
                    else
                    {
                        Graphics.Blit(GetRenderTextureForCamera(VarjoViewCamera.CAMERA_ID.CONTEXT_LEFT), (RenderTexture)null, new Vector2(contextDisplayFactor, -1.0f * contextDisplayFactor), new Vector2(0.0f, contextDisplayFactor));
                    }

                    Profiler.EndSample();
                }

                Plugin.IssuePluginEvent(VarjoPlugin.VARJO_RENDER_EVT_SUBMIT);
                GL.InvalidateState();

                beginFrameCalled = false;
                Profiler.EndSample();
            }
        }
Example #8
0
        private void Update()
        {
            // Empty the lock message queue
            lock (logMessages)
            {
                while (logMessages.Count > 0)
                {
                    var txt = logMessages.Dequeue();
                    if (debug)
                    {
                        Debug.Log(txt);
                    }
                }
            }

            if (!VarjoPlugin.SessionValid)
            {
                return;
            }

            // Update events
            buttonEvents.Clear();
            Profiler.BeginSample("Varjo.PollEvents");
            while (VarjoPlugin.PollEvent(ref eventType))
            {
                switch ((VarjoPlugin.EventType)eventType)
                {
                // Keep track of application visibility and standby status
                // and enable and disable rendering based on that
                case VarjoPlugin.EventType.EVENT_VISIBILITY:
                    layerVisible = VarjoPlugin.GetEventVisibility().visible != 0;
                    if (OnVisibilityEvent != null)
                    {
                        OnVisibilityEvent(layerVisible);
                    }
                    break;

                case VarjoPlugin.EventType.EVENT_HEADSET_STANDBY_STATUS:
                    inStandBy = VarjoPlugin.GetEventHeadsetStandbyStatus().onStandby != 0;
                    if (OnStandbyEvent != null)
                    {
                        OnStandbyEvent(inStandBy);
                    }
                    break;

                case VarjoPlugin.EventType.EVENT_FOREGROUND:
                    if (OnForegroundEvent != null)
                    {
                        OnForegroundEvent(VarjoPlugin.GetEventForeground().isForeground != 0);
                    }
                    break;

                // Update headset button states
                case VarjoPlugin.EventType.EVENT_BUTTON:
                    buttonEvents.Add(VarjoPlugin.GetEventButton());
                    break;

                case VarjoPlugin.EventType.EVENT_MR_DEVICE_STATUS:
                    if (OnMRDeviceStatusEvent != null)
                    {
                        OnMRDeviceStatusEvent(VarjoPlugin.GetEventMRDeviceStatus().status == VarjoPlugin.MRDeviceStatus.Connected);
                    }
                    break;

                case VarjoPlugin.EventType.EVENT_MR_CAMERA_PROPERTY_CHANGE:
                    if (OnMRCameraPropertyChangeEvent != null)
                    {
                        OnMRCameraPropertyChangeEvent(VarjoPlugin.GetEventMRCameraPropertyChange().type);
                    }
                    break;

                case VarjoPlugin.EventType.EVENT_DATA_STREAM_START:
                    if (OnDataStreamStartEvent != null)
                    {
                        OnDataStreamStartEvent(VarjoPlugin.GetEventDataStreamStart().streamId);
                    }
                    break;

                case VarjoPlugin.EventType.EVENT_DATA_STREAM_STOP:
                    if (OnDataStreamStopEvent != null)
                    {
                        OnDataStreamStopEvent(VarjoPlugin.GetEventDataStreamStop().streamId);
                    }
                    break;
                }
            }
            Profiler.EndSample();

            // Call waitsync and sync the render thread
            if (layerVisible && !inStandBy)
            {
                Profiler.BeginSample("Varjo.WaitSync");
                Plugin.IssuePluginEvent(VarjoPlugin.VARJO_RENDER_EVT_WAITSYNC);
                VarjoPlugin.SyncRenderThread();
                Profiler.EndSample();
            }

            // Fetch fresh pose data and cache it
            VarjoPlugin.GetFramePoseData(ref latestFramePose);

            // Update layers
            foreach (var layer in layers)
            {
                layer.UpdateFromManager();
            }

            // Start rendering only if layer is visible
            if (layerVisible && !inStandBy)
            {
                if (!beginFrameCalled)
                {
                    EnableAllViewportCameras(true);
                    Plugin.IssuePluginEvent(VarjoPlugin.VARJO_RENDER_EVT_BEGIN_FRAME);
                    beginFrameCalled = true;
                }
            }
            else
            {
                EnableAllViewportCameras(false);
            }
        }
Example #9
0
        private new void Awake()
        {
            unityThread = Thread.CurrentThread;

            if (_instance == null)
            {
                _instance = this;
            }
            else
            {
                Debug.LogError("Multiple instances of VarjoManager. Destroying the new one.");
                Destroy(gameObject);
                return;
            }

            Plugin = new VarjoPlugin();

            VarjoSystemPresent = VarjoPlugin.IsVarjoSystemInstalled();
            if (!VarjoSystemPresent)
            {
                Debug.LogWarning("Varjo system not found.");
                gameObject.SetActive(false);
                return;
            }

            if (forceVRSupport)
            {
                XRSettings.enabled = true;
                if (XRSettings.supportedDevices != null && XRSettings.supportedDevices.Contains("OpenVR"))
                {
                    if (XRSettings.loadedDeviceName != "OpenVR")
                    {
                        XRSettings.LoadDeviceByName("OpenVR");
                    }
                }
                else
                {
                    Debug.LogError("OpenVR is not in the list of supported Virtual Reality SDKs. You need to add it to the list in Player Settings.");
                }
            }
            else
            {
                if (!XRSettings.enabled)
                {
                    Debug.LogError("Virtual Reality Support is not enabled. Enable Force VR Support in VarjoManager or enable Virtual Reality Support in Player Settings.");
                }
            }


            if (disableVSync)
            {
                QualitySettings.vSyncCount = 0;
            }

            base.Awake();

            if (varjoCamera)
            {
                varjoCamera.gameObject.tag = "MainCamera";
            }
            else
            {
                GameObject go = new GameObject("Varjo Camera");
                go.transform.SetParent(transform);
                varjoCamera = go.AddComponent <Camera>();
                go.tag      = "MainCamera";
            }

            DisableVRCameras();
            DisableExtraAudioListeners();

            StartCoroutine(InitializeSession());
        }
Example #10
0
        /// <summary>
        /// Gets a render texture for a camera with correct dimensions and format.
        /// Creates a texture if it's not created. VarjoManager takes care of texture destruction.
        /// </summary>
        /// <param name="cameraId">Camera Id</param>
        /// <returns>Render texture</returns>
        public RenderTexture GetRenderTextureForCamera(VarjoViewCamera.CAMERA_ID cameraId)
        {
            Profiler.BeginSample("Varjo.GetRenderTextureForCamera");
            if (!VarjoPlugin.SessionValid)
            {
                Debug.LogError("GetRenderTextureForCamera called without a valid session.");
                Profiler.EndSample();
                return(null);
            }

            var texDesc = VarjoPlugin.GetRenderTextureFormat((int)cameraId);

            if (texDesc.width <= 0 || texDesc.height <= 0)
            {
                Debug.Log(string.Format("Invalid texture descriptor: {0}x{1} {2}", texDesc.width, texDesc.height, texDesc.format));
                Profiler.EndSample();
                return(null);
            }

            int camIndex = (int)cameraId;

            if (camRenderTextures[camIndex] != null)
            {
                Profiler.EndSample();
                return(camRenderTextures[camIndex]);
            }

            // TODO: framebuffer dimensions can change per frame.

            Debug.Log(string.Format("Creating render target: {0}x{1}", texDesc.width, texDesc.height));
            RenderTextureDescriptor rtd = new RenderTextureDescriptor()
            {
                width           = texDesc.width,
                height          = texDesc.height,
                colorFormat     = ConvertPluginRenderTextureFormat(texDesc.format),
                depthBufferBits = 32,
                dimension       = TextureDimension.Tex2D,
                volumeDepth     = 1,
                msaaSamples     = 1, // TODO: get the correct MSAA
                sRGB            = true,
            };

            camRenderTextures[camIndex] = new RenderTexture(rtd);
            camRenderTextures[camIndex].Create();
            // Also create the swapchain
            var cfg = new VarjoPlugin.SwapchainConfig()
            {
                format           = VarjoPlugin.varjo_TextureFormat_R8G8B8A8_SRGB,
                numberOfTextures = 4,
                textureWidth     = texDesc.width,
                textureHeight    = texDesc.height,
                arraySize        = 1
            };

            camSwapchains[camIndex] = VarjoPlugin.CreateD3D11Swapchain(cfg);
            // And depth swapchain if requested
            if (submitDepth)
            {
                cfg.format = VarjoPlugin.varjo_DepthTextureFormat_D32_FLOAT;
                camDepthSwapchains[camIndex] = VarjoPlugin.CreateD3D11Swapchain(cfg);
            }

            // Hook up the texture directly to the view struct so that we don't have to call GetNativeTexturePtr() every frame
            var view = submitLayer.views[camIndex];

            view.unityColorTex = camRenderTextures[camIndex].GetNativeTexturePtr();
            if (submitDepth)
            {
                view.unityDepthTex = camRenderTextures[camIndex].GetNativeDepthBufferPtr();
            }

            submitLayer.views[camIndex] = view;

            Profiler.EndSample();
            return(camRenderTextures[camIndex]);
        }