Example #1
0
        static void Main(string[] args)
        {
            _useOculus = true;
            if (!VRContext.IsOculusSupported())
            {
                _useOculus = false;
                if (!VRContext.IsOpenVRSupported())
                {
                    Console.WriteLine("This sample requires an Oculus or OpenVR-capable headset.");
                    return;
                }
            }

            Sdl2Window window = VeldridStartup.CreateWindow(
                new WindowCreateInfo(
                    Sdl2Native.SDL_WINDOWPOS_CENTERED, Sdl2Native.SDL_WINDOWPOS_CENTERED,
                    1280, 720,
                    WindowState.Normal,
                    "Veldrid.VirtualReality Sample"));

            VRContextOptions options = new VRContextOptions
            {
                EyeFramebufferSampleCount = TextureSampleCount.Count4
            };
            VRContext vrContext = _useOculus ? VRContext.CreateOculus(options) : VRContext.CreateOpenVR(options);

            GraphicsBackend backend = GraphicsBackend.Direct3D11;

            bool debug = false;

#if DEBUG
            debug = true;
#endif

            GraphicsDeviceOptions gdo = new GraphicsDeviceOptions(debug, null, false, ResourceBindingModel.Improved, true, true, true);

            if (backend == GraphicsBackend.Vulkan)
            {
                // Oculus runtime causes validation errors.
                gdo.Debug = false;
            }

            (GraphicsDevice gd, Swapchain sc) = CreateDeviceAndSwapchain(window, vrContext, backend, gdo);
            window.Resized += () => sc.Resize((uint)window.Width, (uint)window.Height);

            vrContext.Initialize(gd);

            ImGuiRenderer igr = new ImGuiRenderer(gd, sc.Framebuffer.OutputDescription, window.Width, window.Height, ColorSpaceHandling.Linear);
            window.Resized += () => igr.WindowResized(window.Width, window.Height);

            AssimpMesh mesh = new AssimpMesh(
                gd,
                vrContext.LeftEyeFramebuffer.OutputDescription,
                Path.Combine(AppContext.BaseDirectory, "cat", "cat.obj"),
                Path.Combine(AppContext.BaseDirectory, "cat", "cat_diff.png"));

            Skybox skybox = new Skybox(
                Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, "skybox", "miramar_ft.png")),
                Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, "skybox", "miramar_bk.png")),
                Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, "skybox", "miramar_lf.png")),
                Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, "skybox", "miramar_rt.png")),
                Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, "skybox", "miramar_up.png")),
                Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, "skybox", "miramar_dn.png")));
            skybox.CreateDeviceObjects(gd, vrContext.LeftEyeFramebuffer.OutputDescription);

            CommandList windowCL = gd.ResourceFactory.CreateCommandList();
            CommandList eyesCL   = gd.ResourceFactory.CreateCommandList();

            MirrorTextureEyeSource eyeSource = MirrorTextureEyeSource.BothEyes;

            Stopwatch sw            = Stopwatch.StartNew();
            double    lastFrameTime = sw.Elapsed.TotalSeconds;

            while (window.Exists)
            {
                double newFrameTime = sw.Elapsed.TotalSeconds;
                double deltaSeconds = newFrameTime - lastFrameTime;
                lastFrameTime = newFrameTime;

                InputSnapshot snapshot = window.PumpEvents();
                if (!window.Exists)
                {
                    break;
                }
                InputTracker.UpdateFrameInput(snapshot, window);
                HandleInputs(deltaSeconds);

                igr.Update(1f / 60f, snapshot);

                if (ImGui.BeginMainMenuBar())
                {
                    if (ImGui.BeginMenu("Settings"))
                    {
                        if (ImGui.BeginMenu("Mirror Texture"))
                        {
                            if (ImGui.MenuItem("Both Eyes", null, eyeSource == MirrorTextureEyeSource.BothEyes))
                            {
                                eyeSource = MirrorTextureEyeSource.BothEyes;
                            }
                            if (ImGui.MenuItem("Left Eye", null, eyeSource == MirrorTextureEyeSource.LeftEye))
                            {
                                eyeSource = MirrorTextureEyeSource.LeftEye;
                            }
                            if (ImGui.MenuItem("Right Eye", null, eyeSource == MirrorTextureEyeSource.RightEye))
                            {
                                eyeSource = MirrorTextureEyeSource.RightEye;
                            }

                            ImGui.EndMenu();
                        }

                        if (ImGui.BeginMenu("VR API"))
                        {
                            if (ImGui.MenuItem("Oculus", null, _useOculus) && !_useOculus)
                            {
                                _useOculus       = true;
                                _switchVRContext = true;
                            }
                            if (ImGui.MenuItem("OpenVR", null, !_useOculus) && _useOculus)
                            {
                                _useOculus       = false;
                                _switchVRContext = true;
                            }

                            ImGui.EndMenu();
                        }

                        ImGui.EndMenu();
                    }

                    ImGui.EndMainMenuBar();
                }

                windowCL.Begin();
                windowCL.SetFramebuffer(sc.Framebuffer);
                windowCL.ClearColorTarget(0, new RgbaFloat(0f, 0f, 0.2f, 1f));
                vrContext.RenderMirrorTexture(windowCL, sc.Framebuffer, eyeSource);
                igr.Render(gd, windowCL);
                windowCL.End();
                gd.SubmitCommands(windowCL);
                gd.SwapBuffers(sc);

                HmdPoseState poses = vrContext.WaitForPoses();

                // Render Eyes
                eyesCL.Begin();

                eyesCL.PushDebugGroup("Left Eye");
                Matrix4x4 leftView = poses.CreateView(VREye.Left, _userPosition, -Vector3.UnitZ, Vector3.UnitY);
                RenderEye(eyesCL, vrContext.LeftEyeFramebuffer, mesh, skybox, poses.LeftEyeProjection, leftView);
                eyesCL.PopDebugGroup();

                eyesCL.PushDebugGroup("Right Eye");
                Matrix4x4 rightView = poses.CreateView(VREye.Right, _userPosition, -Vector3.UnitZ, Vector3.UnitY);
                RenderEye(eyesCL, vrContext.RightEyeFramebuffer, mesh, skybox, poses.RightEyeProjection, rightView);
                eyesCL.PopDebugGroup();

                eyesCL.End();
                gd.SubmitCommands(eyesCL);

                vrContext.SubmitFrame();

                if (_switchVRContext)
                {
                    _switchVRContext = false;
                    vrContext.Dispose();
                    vrContext = _useOculus ? VRContext.CreateOculus() : VRContext.CreateOpenVR();
                    vrContext.Initialize(gd);
                }
            }

            vrContext.Dispose();
            gd.Dispose();
        }