xo-imgui: support dynamic vsync_enabled setting + demo in ex4
This commit is contained in:
parent
5fcfadce9a
commit
b4a8ecd7d6
5 changed files with 58 additions and 14 deletions
|
|
@ -741,7 +741,7 @@ DrawState::draw_gc_state(const AppState & app_state,
|
|||
/* TODO: does this reset coord space? */
|
||||
ImRect alloc_rect;
|
||||
{
|
||||
ImGui::BeginChild("top pane", ImVec2(0, 105), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY);
|
||||
ImGui::BeginChild("top pane", ImVec2(0, 200), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY);
|
||||
|
||||
alloc_rect = ImRect(canvas_rect.top_left() + ImGui::GetWindowContentRegionMin(),
|
||||
canvas_rect.top_left() + ImGui::GetWindowContentRegionMax());
|
||||
|
|
@ -817,7 +817,7 @@ DrawState::draw_gc_state(const AppState & app_state,
|
|||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::Text("placeholder text");
|
||||
//ImGui::Text("placeholder text"); // appears below history_rect
|
||||
|
||||
/* BeginChild() again ? */
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ struct DrawState {
|
|||
public:
|
||||
/** when true display imgui demo window **/
|
||||
bool show_demo_window_ = false;
|
||||
/** whether vsync feature enabled (throttle to ~60 fps) **/
|
||||
bool vsync_enabled_ = true;
|
||||
|
||||
draw_state_type state_type_ = draw_state_type::alloc;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace {
|
|||
*p_f = 0.0f;
|
||||
*p_counter = 0;
|
||||
|
||||
return [p_app_state, p_draw_state, p_f, p_counter](ImGuiContext * imgui_cx)
|
||||
return [p_app_state, p_draw_state, p_f, p_counter](VulkanApp * vulkan_app, ImGuiContext * imgui_cx)
|
||||
{
|
||||
scope log(XO_DEBUG(false));
|
||||
|
||||
|
|
@ -108,6 +108,19 @@ namespace {
|
|||
ImGui::End();
|
||||
# endif
|
||||
|
||||
// 0. main menubar
|
||||
if (ImGui::BeginMainMenuBar()) {
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
bool x = vulkan_app->vsync_enabled_flag();
|
||||
|
||||
if (ImGui::MenuItem("vsync", nullptr, &x)) {
|
||||
vulkan_app->update_vsync_enabled(x);
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
// 1. create a simple ImGui window
|
||||
ImGui::Begin("Hello, Vulkan + SDL2!");
|
||||
ImGui::Text("This is a minimal ImGui + Vulkan + SDL2 example!");
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
class VulkanApp {
|
||||
public:
|
||||
using ImguiDrawFn = std::function<ImDrawData * (ImGuiContext *)>;
|
||||
using ImguiDrawFn = std::function<ImDrawData * (VulkanApp *, ImGuiContext *)>;
|
||||
|
||||
public:
|
||||
/* create single-window vulkan application;
|
||||
|
|
@ -21,9 +21,17 @@ public:
|
|||
*/
|
||||
VulkanApp(ImguiDrawFn fn);
|
||||
|
||||
bool vsync_enabled_flag() const { return vsync_enabled_flag_; }
|
||||
|
||||
/* update vsync enabled (will recreate xswapchain at next opportunity)
|
||||
*/
|
||||
void update_vsync_enabled(bool flag);
|
||||
|
||||
/* run application; borrows calling thread for event loop,
|
||||
* until application exit.
|
||||
* Invoke load_fonts once imgui context established
|
||||
* @ref vsync_enabled_flag_. true for VK_PRESENT_MODE_FIFO_KHR;
|
||||
* false for VK_PRESENT_MODE_IMMEDIATE_KHR
|
||||
*/
|
||||
void run(std::function<void (ImGuiContext *)> load_fonts);
|
||||
|
||||
|
|
@ -47,7 +55,10 @@ private:
|
|||
*/
|
||||
void init_sdl_window();
|
||||
|
||||
/* setup vulkan state. swapchain, command buffers etc */
|
||||
/* setup vulkan state. swapchain, command buffers etc
|
||||
* @ref vsync_enabled_flag_. true for VK_PRESENT_MODE_FIFO_KHR;
|
||||
* false for VK_PRESENT_MODE_IMMEDIATE_KHR
|
||||
*/
|
||||
void init_vulkan();
|
||||
|
||||
/* create vulkan instance.
|
||||
|
|
@ -74,6 +85,8 @@ private:
|
|||
/* populates @ref swapchain_, @ref swapchain_images_,
|
||||
* @ref swapchain_image_views_, @ref framebuffers_.
|
||||
* Also $ref render_pass_ iff @p create_render_pass_flag
|
||||
* @ref vsync_enabled_flag_. true for VK_PRESENT_MODE_FIFO_KHR;
|
||||
* false for VK_PRESENT_MODE_IMMEDIATE_KHR
|
||||
*/
|
||||
void create_xswapchain(bool create_render_pass_flag);
|
||||
|
||||
|
|
@ -175,6 +188,10 @@ private:
|
|||
|
||||
/* abstraction for presentation area (?) */
|
||||
VkSurfaceKHR surface_;
|
||||
/* true -> VK_PRESENT_MODE_FIFO_KHR
|
||||
* false -> VK_PRESENT_MODE_IMMEDIATE_KHR
|
||||
*/
|
||||
bool vsync_enabled_flag_ = true;
|
||||
|
||||
/* physical device (graphics card) */
|
||||
VkPhysicalDevice physical_device_;
|
||||
|
|
@ -210,10 +227,14 @@ private:
|
|||
const size_t c_max_frames_in_flight = 2;
|
||||
/* true iff @ref setup has been called */
|
||||
bool setup_flag_ = false;
|
||||
/* true when window resize behavior detected,
|
||||
* until swapchain in consistent state.
|
||||
/* true if xswapchain is out-of-date.
|
||||
* reset when xswapchain recreated (and therefore in consistent state).
|
||||
*
|
||||
* Triggered by:
|
||||
* - window resize
|
||||
* - vsync toggled
|
||||
*/
|
||||
bool framebuffer_resized_flag_ = false;
|
||||
bool xswapchain_recreate_flag_ = false;
|
||||
bool quit_flag_ = false;
|
||||
|
||||
/** draw imgui **/
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ VulkanApp::create_swapchain()
|
|||
create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
create_info.preTransform = capabilities.currentTransform;
|
||||
create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
create_info.presentMode = (vsync_enabled_flag_ ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR);
|
||||
create_info.clipped = VK_TRUE;
|
||||
|
||||
if (vkCreateSwapchainKHR(device_, &create_info, nullptr, &(this->swapchain_)) != VK_SUCCESS) {
|
||||
|
|
@ -564,7 +564,7 @@ VulkanApp::draw_frame()
|
|||
|
||||
result = vkQueuePresentKHR(graphics_queue_, &presentInfo);
|
||||
|
||||
if (framebuffer_resized_flag_)
|
||||
if (xswapchain_recreate_flag_)
|
||||
result = VK_ERROR_OUT_OF_DATE_KHR;
|
||||
|
||||
switch (result) {
|
||||
|
|
@ -572,7 +572,6 @@ VulkanApp::draw_frame()
|
|||
break;
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
case VK_SUBOPTIMAL_KHR:
|
||||
framebuffer_resized_flag_ = false;
|
||||
this->recreate_xswapchain();
|
||||
break;
|
||||
default:
|
||||
|
|
@ -582,6 +581,12 @@ VulkanApp::draw_frame()
|
|||
this->current_frame_ = (current_frame_ + 1) % c_max_frames_in_flight;
|
||||
}
|
||||
|
||||
void
|
||||
VulkanApp::update_vsync_enabled(bool flag) {
|
||||
this->vsync_enabled_flag_ = flag;
|
||||
this->xswapchain_recreate_flag_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
VulkanApp::record_command_buffer(VkCommandBuffer cmdbuf, uint32_t image_ix)
|
||||
{
|
||||
|
|
@ -633,7 +638,7 @@ VulkanApp::record_command_buffer(VkCommandBuffer cmdbuf, uint32_t image_ix)
|
|||
}
|
||||
#endif
|
||||
|
||||
ImDrawData * draw_data = imgui_draw_frame_(imgui_cx_); (void)draw_data;
|
||||
ImDrawData * draw_data = imgui_draw_frame_(this, imgui_cx_);
|
||||
|
||||
ImGui_ImplVulkan_RenderDrawData(draw_data, cmdbuf);
|
||||
|
||||
|
|
@ -671,11 +676,14 @@ VulkanApp::recreate_xswapchain()
|
|||
// wait until device idle before cleaning up resources
|
||||
vkDeviceWaitIdle(device_);
|
||||
|
||||
// remember consistent swapchain state restored
|
||||
this->xswapchain_recreate_flag_ = false;
|
||||
|
||||
// cleanup old xswapchain
|
||||
this->cleanup_xswapchain();
|
||||
|
||||
// create new swapchain
|
||||
this->create_xswapchain(false);
|
||||
this->create_xswapchain(false /*create_render_pass_flag*/);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue