/// <summary> /// main window loop, exits on GLFW3 exit event. Before entering the rendering loop, the following methods are called: /// - initVulkan (device, queues and swapchain creations). /// - OnResize (create there your frame buffers couple to the swapchain and trigger the recording of your command buffers for the presentation. /// - UpdateView (generaly used when the camera setup has changed to update MVP matrices) /// The rendering loop consist of the following steps: /// - render (the default one will submit the default command buffers to the presentQueue and trigger a queue present for each swapchain images. /// - if the `updateViewRequested` field is set to 'true', call the `UpdateView` method. /// - frame counting and chrono. /// - if elapsed time reached `UpdateFrequency` value, the `Update` method is called and the elapsed time chrono is reseet. /// - GLFW events are polled at the end of the loop. /// </summary> public virtual void Run() { initVulkan(); OnResize(); UpdateView(); frameChrono = Stopwatch.StartNew(); long totTime = 0; while (!Glfw3.WindowShouldClose(hWin)) { render(); if (updateViewRequested) { UpdateView(); } frameCount++; if (frameChrono.ElapsedMilliseconds > UpdateFrequency) { Update(); frameChrono.Stop(); totTime += frameChrono.ElapsedMilliseconds; fps = (uint)((double)frameCount / (double)totTime * 1000.0); Glfw3.SetWindowTitle(hWin, "FPS: " + fps.ToString()); if (totTime > 2000) { frameCount = 0; totTime = 0; } frameChrono.Restart(); } Glfw3.PollEvents(); } }