diff --git a/.copyrightignore b/.copyrightignore index 74e1a49001..66cb1f1d51 100644 --- a/.copyrightignore +++ b/.copyrightignore @@ -26,3 +26,4 @@ khrplatform.h clang_format.py run-clang-tidy.py package-list.txt +.spv diff --git a/app/plugins/real_time_shader_selection/real_time_shader_selection.cpp b/app/plugins/real_time_shader_selection/real_time_shader_selection.cpp index d5f3251163..269739b9a2 100644 --- a/app/plugins/real_time_shader_selection/real_time_shader_selection.cpp +++ b/app/plugins/real_time_shader_selection/real_time_shader_selection.cpp @@ -26,7 +26,8 @@ RealTimeShaderSelection::RealTimeShaderSelection() : "Enable dynamic shader selection for samples.", {vkb::Hook::OnAppStart, vkb::Hook::OnUpdateUi}, {&realtimeshaderselection_flag}), - activeShader(0) + active_shader(0), + min_size_for_shaders(2) { } @@ -41,59 +42,62 @@ void RealTimeShaderSelection::init(const vkb::CommandParser &parser) void RealTimeShaderSelection::on_app_start(const std::string &app_info) { - if (platform->get_available_shaders().size() < min_size_for_shaders) + if (platform->get_app().get_available_shaders().size() < min_size_for_shaders) { - LOGE("Sample doesn't support RealTimeShaderSelection plugin, sample should add available shaders please see ApiVulkanSample::store_shader."); - LOGE("Sample, defined {} shaders, minimum number of defined shaders is {}", platform->get_available_shaders().size(), min_size_for_shaders); + LOGE("Sample doesn't support RealTimeShaderSelection plugin, sample should add available shaders please see Application::store_shaders."); + LOGE("Sample, defined {} shaders, minimum number of defined shaders is {}", platform->get_app().get_available_shaders().size(), min_size_for_shaders); return; } - availableShaders = platform->get_available_shaders(); - for (auto const& shader : availableShaders) + + for (auto const &shader : platform->get_app().get_available_shaders()) { - switch(shader.first) + switch (shader.first) { - case vkb::ShaderSourceLanguage::VK_GLSL: - shaderName.emplace_back("GLSL"); - break; - case vkb::ShaderSourceLanguage::VK_HLSL: - shaderName.emplace_back("HLSL"); - break; - case vkb::ShaderSourceLanguage::VK_SPV: - shaderName.emplace_back("SPV"); - break; + case vkb::ShaderSourceLanguage::GLSL: + language_names.emplace_back("GLSL"); + break; + case vkb::ShaderSourceLanguage::HLSL: + language_names.emplace_back("HLSL"); + break; + case vkb::ShaderSourceLanguage::SPV: + language_names.emplace_back("SPV"); + break; + default: + LOGE("Not supported shader language"); + assert(false); } } } void RealTimeShaderSelection::on_update_ui_overlay(vkb::Drawer &drawer) { - if (availableShaders.size() >= min_size_for_shaders) + if (platform->get_app().get_available_shaders().size() >= min_size_for_shaders) { if (drawer.header("Real Time Shader Selection")) { - if (drawer.combo_box("Shader language", &activeShader, shaderName)) + if (drawer.combo_box("Shader language", &active_shader, language_names)) { - std::string selectedShader = shaderName[activeShader]; - vkb::ShaderSourceLanguage shaderType = vkb::ShaderSourceLanguage::VK_GLSL; + std::string selectedShader = language_names[active_shader]; + vkb::ShaderSourceLanguage shaderType = vkb::ShaderSourceLanguage::GLSL; if (selectedShader == "GLSL") { - shaderType = vkb::ShaderSourceLanguage::VK_GLSL; + shaderType = vkb::ShaderSourceLanguage::GLSL; } else if (selectedShader == "HLSL") { - shaderType = vkb::ShaderSourceLanguage::VK_HLSL; + shaderType = vkb::ShaderSourceLanguage::HLSL; } else if (selectedShader == "SPV") { - shaderType = vkb::ShaderSourceLanguage::VK_SPV; + shaderType = vkb::ShaderSourceLanguage::SPV; } else { - return; + LOGE("Not supported shader language"); + assert(false); } - auto it = availableShaders.find(shaderType); - auto app = &platform->get_app(); - app->change_shader(it->first, it->second); + auto it = platform->get_app().get_available_shaders().find(shaderType); + platform->get_app().change_shader(it->first); } } } diff --git a/app/plugins/real_time_shader_selection/real_time_shader_selection.h b/app/plugins/real_time_shader_selection/real_time_shader_selection.h index 8161818d7f..8969270f47 100644 --- a/app/plugins/real_time_shader_selection/real_time_shader_selection.h +++ b/app/plugins/real_time_shader_selection/real_time_shader_selection.h @@ -17,10 +17,10 @@ #pragma once -#include "platform/plugins/plugin_base.h" #include "common/vk_common.h" -#include +#include "platform/plugins/plugin_base.h" #include +#include namespace plugins { @@ -32,7 +32,7 @@ using RealTimeShaderSelectionTags = vkb::PluginBase>> availableShaders; - std::vector shaderName; - int activeShader; - static const int min_size_for_shaders = 2; + private: + std::vector language_names; + int active_shader; + const int min_size_for_shaders; }; } // namespace plugins \ No newline at end of file diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 41b3dde3db..cfb0683dec 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -22,6 +22,7 @@ project(framework LANGUAGES C CXX) set(FRAMEWORK_FILES # Header Files gui.h + drawer.h glsl_compiler.h spirv_reflection.h gltf_loader.h @@ -51,6 +52,7 @@ set(FRAMEWORK_FILES hpp_vulkan_sample.h # Source Files gui.cpp + drawer.cpp glsl_compiler.cpp spirv_reflection.cpp gltf_loader.cpp diff --git a/framework/api_vulkan_sample.cpp b/framework/api_vulkan_sample.cpp index 2e2134da18..62c62ce56b 100644 --- a/framework/api_vulkan_sample.cpp +++ b/framework/api_vulkan_sample.cpp @@ -100,25 +100,6 @@ void ApiVulkanSample::update(float delta_time) } } -void ApiVulkanSample::update_overlay(float delta_time, const std::function& additional_ui) -{ - if (gui) - { - gui->show_simple_window(get_name(), vkb::to_u32(1.0f / delta_time), [this, additional_ui]() { - on_update_ui_overlay(gui->get_drawer()); - additional_ui(); - }); - - gui->update(delta_time); - - if (gui->update_buffers() || gui->get_drawer().is_dirty()) - { - build_command_buffers(); - gui->get_drawer().clear(); - } - } -} - bool ApiVulkanSample::resize(const uint32_t _width, const uint32_t _height) { if (!prepared) @@ -449,18 +430,37 @@ void ApiVulkanSample::create_pipeline_cache() VK_CHECK(vkCreatePipelineCache(device->get_handle(), &pipeline_cache_create_info, nullptr, &pipeline_cache)); } -VkPipelineShaderStageCreateInfo ApiVulkanSample::load_shader(const std::string &file, VkShaderStageFlagBits stage) +VkPipelineShaderStageCreateInfo ApiVulkanSample::load_shader(const std::string &file, VkShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language) { VkPipelineShaderStageCreateInfo shader_stage = {}; shader_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shader_stage.stage = stage; - shader_stage.module = vkb::load_shader(file.c_str(), device->get_handle(), stage); + shader_stage.module = vkb::load_shader(file.c_str(), device->get_handle(), stage, src_language); shader_stage.pName = "main"; assert(shader_stage.module != VK_NULL_HANDLE); shader_modules.push_back(shader_stage.module); return shader_stage; } +void ApiVulkanSample::update_overlay(float delta_time, const std::function &additional_ui) +{ + if (gui) + { + gui->show_simple_window(get_name(), vkb::to_u32(1.0f / delta_time), [this, additional_ui]() { + on_update_ui_overlay(gui->get_drawer()); + additional_ui(); + }); + + gui->update(delta_time); + + if (gui->update_buffers() || gui->get_drawer().is_dirty()) + { + build_command_buffers(); + gui->get_drawer().clear(); + } + } +} + void ApiVulkanSample::draw_ui(const VkCommandBuffer command_buffer) { if (gui) @@ -860,11 +860,6 @@ void ApiVulkanSample::update_render_pass_flags(uint32_t flags) void ApiVulkanSample::on_update_ui_overlay(vkb::Drawer &drawer) {} -void ApiVulkanSample::store_shader(const vkb::ShaderSourceLanguage& shaderLanguage, const std::vector>& listOfShader) -{ - Application::get_available_shaders().insert({shaderLanguage, listOfShader}); -} - void ApiVulkanSample::create_swapchain_buffers() { if (render_context->has_swapchain()) diff --git a/framework/api_vulkan_sample.h b/framework/api_vulkan_sample.h index 73d5320cd2..fd630dda5a 100644 --- a/framework/api_vulkan_sample.h +++ b/framework/api_vulkan_sample.h @@ -112,7 +112,7 @@ class ApiVulkanSample : public vkb::VulkanSample virtual void update(float delta_time) override; - virtual void update_overlay(float delta_time, const std::function& additional_ui) override; + virtual void update_overlay(float delta_time, const std::function &additional_ui) override; virtual bool resize(const uint32_t width, const uint32_t height) override; @@ -332,8 +332,9 @@ class ApiVulkanSample : public vkb::VulkanSample * @brief Load a SPIR-V shader * @param file The file location of the shader relative to the shaders folder * @param stage The shader stage + * @param src_language The shader language */ - VkPipelineShaderStageCreateInfo load_shader(const std::string &file, VkShaderStageFlagBits stage); + VkPipelineShaderStageCreateInfo load_shader(const std::string &file, VkShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language = vkb::ShaderSourceLanguage::GLSL); /** * @brief Updates the overlay @@ -369,14 +370,6 @@ class ApiVulkanSample : public vkb::VulkanSample */ virtual void prepare_gui(); - /** - * @brief Stores a list of shaders for the active sample, used by plugins to dynamically change the shader - * - * @param shaderLanguage The shader language for which the shader list will be provided - * @param listOfShader The shader list, where paths and shader types are provided - */ - void store_shader(const vkb::ShaderSourceLanguage& shaderLanguage, const std::vector>& listOfShader); - private: /** brief Indicates that the view (position, rotation) has changed and buffers containing camera matrices need to be updated */ bool view_updated = false; diff --git a/framework/common/hpp_vk_common.h b/framework/common/hpp_vk_common.h index c23464fac6..63cd7f83e3 100644 --- a/framework/common/hpp_vk_common.h +++ b/framework/common/hpp_vk_common.h @@ -90,9 +90,9 @@ inline bool is_dynamic_buffer_descriptor_type(vk::DescriptorType descriptor_type return vkb::is_dynamic_buffer_descriptor_type(static_cast(descriptor_type)); } -inline vk::ShaderModule load_shader(const std::string &filename, vk::Device device, vk::ShaderStageFlagBits stage) +inline vk::ShaderModule load_shader(const std::string &filename, vk::Device device, vk::ShaderStageFlagBits stage, ShaderSourceLanguage src_language = ShaderSourceLanguage::GLSL) { - return static_cast(vkb::load_shader(filename, device, static_cast(stage))); + return static_cast(vkb::load_shader(filename, device, static_cast(stage), src_language)); } inline void set_image_layout(vk::CommandBuffer command_buffer, @@ -135,17 +135,17 @@ inline vk::Framebuffer create_framebuffer(vk::Device device, vk::RenderPass rend return device.createFramebuffer(framebuffer_create_info); } -inline vk::Pipeline create_graphics_pipeline(vk::Device device, - vk::PipelineCache pipeline_cache, - std::array const &shader_stages, - vk::PipelineVertexInputStateCreateInfo const &vertex_input_state, - vk::PrimitiveTopology primitive_topology, - vk::CullModeFlags cull_mode, - vk::FrontFace front_face, - std::vector const &blend_attachment_states, - vk::PipelineDepthStencilStateCreateInfo const &depth_stencil_state, - vk::PipelineLayout pipeline_layout, - vk::RenderPass render_pass) +inline vk::Pipeline create_graphics_pipeline(vk::Device device, + vk::PipelineCache pipeline_cache, + vk::ArrayProxyNoTemporaries const &shader_stages, + vk::PipelineVertexInputStateCreateInfo const &vertex_input_state, + vk::PrimitiveTopology primitive_topology, + vk::CullModeFlags cull_mode, + vk::FrontFace front_face, + std::vector const &blend_attachment_states, + vk::PipelineDepthStencilStateCreateInfo const &depth_stencil_state, + vk::PipelineLayout pipeline_layout, + vk::RenderPass render_pass) { vk::PipelineInputAssemblyStateCreateInfo input_assembly_state({}, primitive_topology, false); diff --git a/framework/common/vk_common.cpp b/framework/common/vk_common.cpp index 03f66d4ed0..f07af30f6a 100644 --- a/framework/common/vk_common.cpp +++ b/framework/common/vk_common.cpp @@ -356,24 +356,37 @@ int32_t get_bits_per_pixel(VkFormat format) } } -VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage) +VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language) { vkb::GLSLCompiler glsl_compiler; - auto buffer = vkb::fs::read_shader_binary(filename); + auto buffer = vkb::fs::read_shader_binary(filename); + std::vector spirv; - std::string file_ext = filename; + if (vkb::ShaderSourceLanguage::GLSL == src_language) + { + std::string file_ext = filename; - // Extract extension name from the glsl shader file - file_ext = file_ext.substr(file_ext.find_last_of(".") + 1); + // Extract extension name from the glsl shader file + file_ext = file_ext.substr(file_ext.find_last_of(".") + 1); - std::vector spirv; - std::string info_log; + std::string info_log; - // Compile the GLSL source - if (!glsl_compiler.compile_to_spirv(vkb::find_shader_stage(file_ext), buffer, "main", {}, spirv, info_log)) + // Compile the GLSL source + if (!glsl_compiler.compile_to_spirv(vkb::find_shader_stage(file_ext), buffer, "main", {}, spirv, info_log)) + { + LOGE("Failed to compile shader, Error: {}", info_log.c_str()); + return VK_NULL_HANDLE; + } + } + else if (vkb::ShaderSourceLanguage::SPV == src_language) + { + spirv = std::vector(reinterpret_cast(buffer.data()), + reinterpret_cast(buffer.data()) + buffer.size() / sizeof(uint32_t)); + } + else { - LOGE("Failed to compile shader, Error: {}", info_log.c_str()); + LOGE("The format is not supported"); return VK_NULL_HANDLE; } diff --git a/framework/common/vk_common.h b/framework/common/vk_common.h index 3bfe92a994..9199833a71 100644 --- a/framework/common/vk_common.h +++ b/framework/common/vk_common.h @@ -1,5 +1,6 @@ -/* Copyright (c) 2018-2021, Arm Limited and Contributors - * Copyright (c) 2019-2021, Sascha Willems +/* Copyright (c) 2018-2023, Arm Limited and Contributors + * Copyright (c) 2019-2023, Sascha Willems + * Copyright (c) 2023, Mobica Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -90,26 +91,11 @@ bool is_buffer_descriptor_type(VkDescriptorType descriptor_type); */ int32_t get_bits_per_pixel(VkFormat format); -typedef enum ShaderSourceLanguage +enum class ShaderSourceLanguage { - VK_GLSL, - VK_HLSL, - VK_SPV, -} ShaderSourceLanguage; - -enum class ShaderType -{ - VERT, - FRAG, - COMP, - GEOM, - TESC, - TESE, - MESH, - TASK, - RGEN, - RCHIT, - RMISS + GLSL, + HLSL, + SPV, }; /** @@ -117,9 +103,10 @@ enum class ShaderType * @param filename The shader location * @param device The logical device * @param stage The shader stage + * @param src_language The shader language * @return The string to return. */ -VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage); +VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage, ShaderSourceLanguage src_language = ShaderSourceLanguage::GLSL); /** * @brief Image memory barrier structure used to define @@ -145,9 +132,9 @@ struct ImageMemoryBarrier }; /** -* @brief Buffer memory barrier structure used to define -* memory access for a buffer during command recording. -*/ + * @brief Buffer memory barrier structure used to define + * memory access for a buffer during command recording. + */ struct BufferMemoryBarrier { VkPipelineStageFlags src_stage_mask{VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT}; @@ -160,8 +147,8 @@ struct BufferMemoryBarrier }; /** -* @brief Put an image memory barrier for setting an image layout on the sub resource into the given command buffer -*/ + * @brief Put an image memory barrier for setting an image layout on the sub resource into the given command buffer + */ void set_image_layout( VkCommandBuffer command_buffer, VkImage image, @@ -172,8 +159,8 @@ void set_image_layout( VkPipelineStageFlags dst_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); /** -* @brief Uses a fixed sub resource layout with first mip level and layer -*/ + * @brief Uses a fixed sub resource layout with first mip level and layer + */ void set_image_layout( VkCommandBuffer command_buffer, VkImage image, @@ -184,8 +171,8 @@ void set_image_layout( VkPipelineStageFlags dst_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); /** -* @brief Insert an image memory barrier into the command buffer -*/ + * @brief Insert an image memory barrier into the command buffer + */ void insert_image_memory_barrier( VkCommandBuffer command_buffer, VkImage image, @@ -210,23 +197,23 @@ struct LoadStoreInfo namespace gbuffer { /** - * @return Load store info to load all and store only the swapchain - */ + * @return Load store info to load all and store only the swapchain + */ std::vector get_load_all_store_swapchain(); /** - * @return Load store info to clear all and store only the swapchain - */ + * @return Load store info to clear all and store only the swapchain + */ std::vector get_clear_all_store_swapchain(); /** - * @return Load store info to clear and store all images - */ + * @return Load store info to clear and store all images + */ std::vector get_clear_store_all(); /** - * @return Default clear values for the G-buffer - */ + * @return Default clear values for the G-buffer + */ std::vector get_clear_value(); } // namespace gbuffer diff --git a/framework/drawer.cpp b/framework/drawer.cpp new file mode 100644 index 0000000000..da59f98bd2 --- /dev/null +++ b/framework/drawer.cpp @@ -0,0 +1,158 @@ +/* Copyright (c) 2023, Mobica Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "drawer.h" + +namespace vkb +{ + +void Drawer::clear() +{ + dirty = false; +} + +bool Drawer::is_dirty() +{ + return dirty; +} + +void Drawer::set_dirty(bool dirty) +{ + this->dirty = dirty; +} + +bool Drawer::header(const char *caption) +{ + return ImGui::CollapsingHeader(caption, ImGuiTreeNodeFlags_DefaultOpen); +} + +bool Drawer::checkbox(const char *caption, bool *value) +{ + bool res = ImGui::Checkbox(caption, value); + if (res) + { + dirty = true; + }; + return res; +} + +bool Drawer::checkbox(const char *caption, int32_t *value) +{ + bool val = (*value == 1); + bool res = ImGui::Checkbox(caption, &val); + *value = val; + if (res) + { + dirty = true; + }; + return res; +} + +bool Drawer::input_float(const char *caption, float *value, float step, uint32_t precision) +{ + bool res = ImGui::InputFloat(caption, value, step, step * 10.0f, precision); + if (res) + { + dirty = true; + }; + return res; +} + +bool Drawer::slider_float(const char *caption, float *value, float min, float max) +{ + bool res = ImGui::SliderFloat(caption, value, min, max); + if (res) + { + dirty = true; + }; + return res; +} + +bool Drawer::slider_int(const char *caption, int32_t *value, int32_t min, int32_t max) +{ + bool res = ImGui::SliderInt(caption, value, min, max); + if (res) + { + dirty = true; + }; + return res; +} + +bool Drawer::combo_box(const char *caption, int32_t *itemindex, std::vector items) +{ + if (items.empty()) + { + return false; + } + std::vector charitems; + charitems.reserve(items.size()); + for (size_t i = 0; i < items.size(); i++) + { + charitems.push_back(items[i].c_str()); + } + uint32_t itemCount = static_cast(charitems.size()); + bool res = ImGui::Combo(caption, itemindex, &charitems[0], itemCount, itemCount); + if (res) + { + dirty = true; + }; + return res; +} + +bool Drawer::button(const char *caption) +{ + bool res = ImGui::Button(caption); + if (res) + { + dirty = true; + }; + return res; +} + +void Drawer::text(const char *formatstr, ...) +{ + va_list args; + va_start(args, formatstr); + ImGui::TextV(formatstr, args); + va_end(args); +} + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) +{ + return ImGui::ColorEdit3(caption, colors, flags); +} + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) +{ + return ImGui::ColorEdit4(caption, colors, flags); +} + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) +{ + return ImGui::ColorPicker3(caption, colors, flags); +} + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) +{ + return ImGui::ColorPicker4(caption, colors, flags); +} + +} // namespace vkb \ No newline at end of file diff --git a/framework/drawer.h b/framework/drawer.h new file mode 100644 index 0000000000..e8faf9b97a --- /dev/null +++ b/framework/drawer.h @@ -0,0 +1,206 @@ +/* Copyright (c) 2023, Mobica Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace vkb +{ +class Drawer; + +/** + * @brief Responsible for drawing new elements into the gui + */ +class Drawer +{ + public: + enum class ColorOp + { + Edit, + Pick + }; + + Drawer() = default; + + /** + * @brief Clears the dirty bit set + */ + void clear(); + + /** + * @brief Returns true if the drawer has been updated + */ + bool is_dirty(); + + /** + * @brief May be used to force drawer update + */ + void set_dirty(bool dirty); + + /** + * @brief Adds a collapsable header item to the gui + * @param caption The text to display + * @returns True if adding item was successful + */ + bool header(const char *caption); + + /** + * @brief Adds a checkbox to the gui + * @param caption The text to display + * @param value The boolean value to map the checkbox to + * @returns True if adding item was successful + */ + bool checkbox(const char *caption, bool *value); + + /** + * @brief Adds a checkbox to the gui + * @param caption The text to display + * @param value The integer value to map the checkbox to + * @returns True if adding item was successful + */ + bool checkbox(const char *caption, int32_t *value); + + /** + * @brief Adds a number input field to the gui + * @param caption The text to display + * @param value The value to map to + * @param step The step increment + * @param precision The precision + * @returns True if adding item was successful + */ + bool input_float(const char *caption, float *value, float step, uint32_t precision); + + /** + * @brief Adds a slide bar to the gui for floating points to the gui + * @param caption The text to display + * @param value The value to map to + * @param min The minimum value + * @param max The maximum value + * @returns True if adding item was successful + */ + bool slider_float(const char *caption, float *value, float min, float max); + + /** + * @brief Adds a slide bar to the gui for integers to the gui + * @param caption The text to display + * @param value The value to map to + * @param min The minimum value + * @param max The maximum value + * @returns True if adding item was successful + */ + bool slider_int(const char *caption, int32_t *value, int32_t min, int32_t max); + + /** + * @brief Adds a multiple choice drop box to the gui + * @param caption The text to display + * @param itemindex The item index to display + * @param items The items to display in the box + * @returns True if adding item was successful + */ + bool combo_box(const char *caption, int32_t *itemindex, std::vector items); + + /** + * @brief Adds a clickable button to the gui + * @param caption The text to display + * @returns True if adding item was successful + */ + bool button(const char *caption); + + /** + * @brief Adds a label to the gui + * @param formatstr The format string + */ + void text(const char *formatstr, ...); + + /** + * @brief Adds a color picker to the gui + * @param caption The text to display + * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. + * @param width Element width. Zero is a special value for the default element width. + * @param flags Flags to modify the appearance and behavior of the element. + */ + bool color_picker(const char *caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0); + + /** + * @brief Adds a color picker to the gui + * @param caption The text to display + * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. + * @param width Element width. Zero is a special value for the default element width. + * @param flags Flags to modify the appearance and behavior of the element. + */ + bool color_picker(const char *caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0); + + /** + * @brief Adds a color edit to the gui + * @param caption The text to display + * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. + * @param width Element width. Zero is a special value for the default element width. + * @param flags Flags to modify the appearance and behavior of the element. + */ + bool color_edit(const char *caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0); + + /** + * @brief Adds a color edit to the gui + * @tparam OP Mode of the color element. + * @tparam N Color channel count. Must be 3 or 4. + * @param caption The text to display + * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. + * @param width Element width. Zero is a special value for the default element width. + * @param flags Flags to modify the appearance and behavior of the element. + */ + template + bool color_op(const std::string &caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0) + { + static_assert((N == 3) || (N == 4), "The channel count must be 3 or 4."); + + ImGui::PushItemWidth(width); + bool res = color_op_impl(caption.c_str(), color.data(), flags); + ImGui::PopItemWidth(); + if (res) + dirty = true; + return res; + } + + private: + template + inline bool color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) + { + assert(false); + return false; + } + + bool dirty{false}; +}; + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); + +template <> +bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); + +} // namespace vkb diff --git a/framework/gui.cpp b/framework/gui.cpp index dc5dc3c2e2..439972338e 100644 --- a/framework/gui.cpp +++ b/framework/gui.cpp @@ -1134,139 +1134,4 @@ bool Gui::input_event(const InputEvent &input_event) return capture_move_event; } -void Drawer::clear() -{ - dirty = false; -} - -bool Drawer::is_dirty() -{ - return dirty; -} - -void Drawer::set_dirty(bool dirty) -{ - this->dirty = dirty; -} - -bool Drawer::header(const char *caption) -{ - return ImGui::CollapsingHeader(caption, ImGuiTreeNodeFlags_DefaultOpen); -} - -bool Drawer::checkbox(const char *caption, bool *value) -{ - bool res = ImGui::Checkbox(caption, value); - if (res) - { - dirty = true; - }; - return res; -} - -bool Drawer::checkbox(const char *caption, int32_t *value) -{ - bool val = (*value == 1); - bool res = ImGui::Checkbox(caption, &val); - *value = val; - if (res) - { - dirty = true; - }; - return res; -} - -bool Drawer::input_float(const char *caption, float *value, float step, uint32_t precision) -{ - bool res = ImGui::InputFloat(caption, value, step, step * 10.0f, precision); - if (res) - { - dirty = true; - }; - return res; -} - -bool Drawer::slider_float(const char *caption, float *value, float min, float max) -{ - bool res = ImGui::SliderFloat(caption, value, min, max); - if (res) - { - dirty = true; - }; - return res; -} - -bool Drawer::slider_int(const char *caption, int32_t *value, int32_t min, int32_t max) -{ - bool res = ImGui::SliderInt(caption, value, min, max); - if (res) - { - dirty = true; - }; - return res; -} - -bool Drawer::combo_box(const char *caption, int32_t *itemindex, std::vector items) -{ - if (items.empty()) - { - return false; - } - std::vector charitems; - charitems.reserve(items.size()); - for (size_t i = 0; i < items.size(); i++) - { - charitems.push_back(items[i].c_str()); - } - uint32_t itemCount = static_cast(charitems.size()); - bool res = ImGui::Combo(caption, itemindex, &charitems[0], itemCount, itemCount); - if (res) - { - dirty = true; - }; - return res; -} - -bool Drawer::button(const char *caption) -{ - bool res = ImGui::Button(caption); - if (res) - { - dirty = true; - }; - return res; -} - -void Drawer::text(const char *formatstr, ...) -{ - va_list args; - va_start(args, formatstr); - ImGui::TextV(formatstr, args); - va_end(args); -} - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorEdit3(caption, colors, flags); -} - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorEdit4(caption, colors, flags); -} - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorPicker3(caption, colors, flags); -} - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorPicker4(caption, colors, flags); -} - } // namespace vkb diff --git a/framework/gui.h b/framework/gui.h index 6282887139..8046238a48 100644 --- a/framework/gui.h +++ b/framework/gui.h @@ -29,6 +29,7 @@ #include "core/command_buffer.h" #include "core/sampler.h" #include "debug_info.h" +#include "drawer.h" #include "platform/filesystem.h" #include "platform/input_events.h" #include "rendering/render_context.h" @@ -75,182 +76,6 @@ struct Font float size{}; }; -/** - * @brief Responsible for drawing new elements into the gui - */ -class Drawer -{ - public: - enum class ColorOp - { - Edit, - Pick - }; - - Drawer() = default; - - /** - * @brief Clears the dirty bit set - */ - void clear(); - - /** - * @brief Returns true if the drawer has been updated - */ - bool is_dirty(); - - /** - * @brief May be used to force drawer update - */ - void set_dirty(bool dirty); - - /** - * @brief Adds a collapsable header item to the gui - * @param caption The text to display - * @returns True if adding item was successful - */ - bool header(const char *caption); - - /** - * @brief Adds a checkbox to the gui - * @param caption The text to display - * @param value The boolean value to map the checkbox to - * @returns True if adding item was successful - */ - bool checkbox(const char *caption, bool *value); - - /** - * @brief Adds a checkbox to the gui - * @param caption The text to display - * @param value The integer value to map the checkbox to - * @returns True if adding item was successful - */ - bool checkbox(const char *caption, int32_t *value); - - /** - * @brief Adds a number input field to the gui - * @param caption The text to display - * @param value The value to map to - * @param step The step increment - * @param precision The precision - * @returns True if adding item was successful - */ - bool input_float(const char *caption, float *value, float step, uint32_t precision); - - /** - * @brief Adds a slide bar to the gui for floating points to the gui - * @param caption The text to display - * @param value The value to map to - * @param min The minimum value - * @param max The maximum value - * @returns True if adding item was successful - */ - bool slider_float(const char *caption, float *value, float min, float max); - - /** - * @brief Adds a slide bar to the gui for integers to the gui - * @param caption The text to display - * @param value The value to map to - * @param min The minimum value - * @param max The maximum value - * @returns True if adding item was successful - */ - bool slider_int(const char *caption, int32_t *value, int32_t min, int32_t max); - - /** - * @brief Adds a multiple choice drop box to the gui - * @param caption The text to display - * @param itemindex The item index to display - * @param items The items to display in the box - * @returns True if adding item was successful - */ - bool combo_box(const char *caption, int32_t *itemindex, std::vector items); - - /** - * @brief Adds a clickable button to the gui - * @param caption The text to display - * @returns True if adding item was successful - */ - bool button(const char *caption); - - /** - * @brief Adds a label to the gui - * @param formatstr The format string - */ - void text(const char *formatstr, ...); - - /** - * @brief Adds a color picker to the gui - * @param caption The text to display - * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. - * @param width Element width. Zero is a special value for the default element width. - * @param flags Flags to modify the appearance and behavior of the element. - */ - bool color_picker(const char *caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0); - - /** - * @brief Adds a color picker to the gui - * @param caption The text to display - * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. - * @param width Element width. Zero is a special value for the default element width. - * @param flags Flags to modify the appearance and behavior of the element. - */ - bool color_picker(const char *caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0); - - /** - * @brief Adds a color edit to the gui - * @param caption The text to display - * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. - * @param width Element width. Zero is a special value for the default element width. - * @param flags Flags to modify the appearance and behavior of the element. - */ - bool color_edit(const char *caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0); - - /** - * @brief Adds a color edit to the gui - * @tparam OP Mode of the color element. - * @tparam N Color channel count. Must be 3 or 4. - * @param caption The text to display - * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. - * @param width Element width. Zero is a special value for the default element width. - * @param flags Flags to modify the appearance and behavior of the element. - */ - template - bool color_op(const std::string &caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0) - { - static_assert((N == 3) || (N == 4), "The channel count must be 3 or 4."); - - ImGui::PushItemWidth(width); - bool res = color_op_impl(caption.c_str(), color.data(), flags); - ImGui::PopItemWidth(); - if (res) - dirty = true; - return res; - } - - private: - template - inline bool color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) - { - assert(false); - return false; - } - - bool dirty{false}; -}; - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - -template <> -bool Drawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - class VulkanSample; /** diff --git a/framework/hpp_api_vulkan_sample.cpp b/framework/hpp_api_vulkan_sample.cpp index 993e78aece..c552badef9 100644 --- a/framework/hpp_api_vulkan_sample.cpp +++ b/framework/hpp_api_vulkan_sample.cpp @@ -410,14 +410,14 @@ void HPPApiVulkanSample::create_pipeline_cache() pipeline_cache = get_device()->get_handle().createPipelineCache({}); } -vk::PipelineShaderStageCreateInfo HPPApiVulkanSample::load_shader(const std::string &file, vk::ShaderStageFlagBits stage) +vk::PipelineShaderStageCreateInfo HPPApiVulkanSample::load_shader(const std::string &file, vk::ShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language) { - shader_modules.push_back(vkb::common::load_shader(file.c_str(), get_device()->get_handle(), stage)); + shader_modules.push_back(vkb::common::load_shader(file.c_str(), get_device()->get_handle(), stage, src_language)); assert(shader_modules.back()); return vk::PipelineShaderStageCreateInfo({}, stage, shader_modules.back(), "main"); } -void HPPApiVulkanSample::update_overlay(float delta_time, const std::function& additional_ui) +void HPPApiVulkanSample::update_overlay(float delta_time, const std::function &additional_ui) { if (gui) { @@ -765,7 +765,7 @@ void HPPApiVulkanSample::update_render_pass_flags(RenderPassCreateFlags flags) render_pass = get_device()->get_handle().createRenderPass(render_pass_create_info); } -void HPPApiVulkanSample::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPApiVulkanSample::on_update_ui_overlay(vkb::Drawer &drawer) {} void HPPApiVulkanSample::create_swapchain_buffers() diff --git a/framework/hpp_api_vulkan_sample.h b/framework/hpp_api_vulkan_sample.h index 24cb788e2e..4fa9b40c28 100644 --- a/framework/hpp_api_vulkan_sample.h +++ b/framework/hpp_api_vulkan_sample.h @@ -280,15 +280,16 @@ class HPPApiVulkanSample : public vkb::HPPVulkanSample * @brief Load a SPIR-V shader * @param file The file location of the shader relative to the shaders folder * @param stage The shader stage + * @param src_language The shader language */ - vk::PipelineShaderStageCreateInfo load_shader(const std::string &file, vk::ShaderStageFlagBits stage); + vk::PipelineShaderStageCreateInfo load_shader(const std::string &file, vk::ShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language = vkb::ShaderSourceLanguage::GLSL); /** * @brief Updates the overlay * @param delta_time The time taken since the last frame * @param additional_ui Function that implements an additional Gui */ - void update_overlay(float delta_time, const std::function& additional_ui) override; + void update_overlay(float delta_time, const std::function &additional_ui) override; /** * @brief If the gui is enabled, then record the drawing commands to a command buffer @@ -311,7 +312,7 @@ class HPPApiVulkanSample : public vkb::HPPVulkanSample * @brief Called when the UI overlay is updating, can be used to add custom elements to the overlay * @param drawer The drawer from the gui to draw certain elements */ - virtual void on_update_ui_overlay(vkb::HPPDrawer &drawer); + virtual void on_update_ui_overlay(vkb::Drawer &drawer); /** * @brief Initializes the UI. Can be overridden to customize the way it is displayed. diff --git a/framework/hpp_gui.cpp b/framework/hpp_gui.cpp index 3126fcaded..51fa3a338a 100644 --- a/framework/hpp_gui.cpp +++ b/framework/hpp_gui.cpp @@ -660,7 +660,7 @@ const HPPGui::StatsView &HPPGui::get_stats_view() const return stats_view; } -HPPDrawer &HPPGui::get_drawer() +Drawer &HPPGui::get_drawer() { return drawer; } @@ -1062,139 +1062,4 @@ bool HPPGui::input_event(const InputEvent &input_event) return capture_move_event; } -void HPPDrawer::clear() -{ - dirty = false; -} - -bool HPPDrawer::is_dirty() const -{ - return dirty; -} - -void HPPDrawer::set_dirty(bool dirty) -{ - this->dirty = dirty; -} - -bool HPPDrawer::header(const std::string &caption) const -{ - return ImGui::CollapsingHeader(caption.c_str(), ImGuiTreeNodeFlags_DefaultOpen); -} - -bool HPPDrawer::checkbox(const std::string &caption, bool *value) -{ - bool res = ImGui::Checkbox(caption.c_str(), value); - if (res) - { - dirty = true; - }; - return res; -} - -bool HPPDrawer::checkbox(const std::string &caption, int32_t *value) -{ - bool val = (*value == 1); - bool res = ImGui::Checkbox(caption.c_str(), &val); - *value = val; - if (res) - { - dirty = true; - }; - return res; -} - -bool HPPDrawer::input_float(const std::string &caption, float *value, float step, uint32_t precision) -{ - bool res = ImGui::InputFloat(caption.c_str(), value, step, step * 10.0f, precision); - if (res) - { - dirty = true; - }; - return res; -} - -bool HPPDrawer::slider_float(const std::string &caption, float *value, float min, float max) -{ - bool res = ImGui::SliderFloat(caption.c_str(), value, min, max); - if (res) - { - dirty = true; - }; - return res; -} - -bool HPPDrawer::slider_int(const std::string &caption, int32_t *value, int32_t min, int32_t max) -{ - bool res = ImGui::SliderInt(caption.c_str(), value, min, max); - if (res) - { - dirty = true; - }; - return res; -} - -bool HPPDrawer::combo_box(const std::string &caption, int32_t *itemindex, std::vector items) -{ - if (items.empty()) - { - return false; - } - std::vector charitems; - charitems.reserve(items.size()); - for (size_t i = 0; i < items.size(); i++) - { - charitems.push_back(items[i].c_str()); - } - uint32_t itemCount = static_cast(charitems.size()); - bool res = ImGui::Combo(caption.c_str(), itemindex, &charitems[0], itemCount, itemCount); - if (res) - { - dirty = true; - }; - return res; -} - -bool HPPDrawer::button(const std::string &caption) -{ - bool res = ImGui::Button(caption.c_str()); - if (res) - { - dirty = true; - }; - return res; -} - -void HPPDrawer::text(const char *formatstr, ...) -{ - va_list args; - va_start(args, formatstr); - ImGui::TextV(formatstr, args); - va_end(args); -} - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorEdit3(caption, colors, flags); -} - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorEdit4(caption, colors, flags); -} - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorPicker3(caption, colors, flags); -} - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) -{ - return ImGui::ColorPicker4(caption, colors, flags); -} - } // namespace vkb diff --git a/framework/hpp_gui.h b/framework/hpp_gui.h index 585cd7bc6a..cc4f2f5fed 100644 --- a/framework/hpp_gui.h +++ b/framework/hpp_gui.h @@ -23,6 +23,7 @@ #include "core/hpp_image_view.h" #include "core/hpp_pipeline_layout.h" #include "debug_info.h" +#include "drawer.h" #include "platform/filesystem.h" #include "platform/input_events.h" #include "stats/hpp_stats.h" @@ -63,155 +64,6 @@ struct HPPFont float size = 0.0f; }; -/** - * @brief Responsible for drawing new elements into the gui - */ -class HPPDrawer -{ - public: - enum class ColorOp - { - Edit, - Pick - }; - - HPPDrawer() = default; - - /** - * @brief Clears the dirty bit set - */ - void clear(); - - /** - * @brief Returns true if the drawer has been updated - */ - bool is_dirty() const; - - /** - * @brief May be used to force drawer update - */ - void set_dirty(bool dirty); - - /** - * @brief Adds a collapsable header item to the gui - * @param caption The text to display - * @returns True if adding item was successful - */ - bool header(const std::string &caption) const; - - /** - * @brief Adds a checkbox to the gui - * @param caption The text to display - * @param value The boolean value to map the checkbox to - * @returns True if adding item was successful - */ - bool checkbox(const std::string &caption, bool *value); - - /** - * @brief Adds a checkbox to the gui - * @param caption The text to display - * @param value The integer value to map the checkbox to - * @returns True if adding item was successful - */ - bool checkbox(const std::string &caption, int32_t *value); - - /** - * @brief Adds a number input field to the gui - * @param caption The text to display - * @param value The value to map to - * @param step The step increment - * @param precision The precision - * @returns True if adding item was successful - */ - bool input_float(const std::string &caption, float *value, float step, uint32_t precision); - - /** - * @brief Adds a slide bar to the gui for floating points to the gui - * @param caption The text to display - * @param value The value to map to - * @param min The minimum value - * @param max The maximum value - * @returns True if adding item was successful - */ - bool slider_float(const std::string &caption, float *value, float min, float max); - - /** - * @brief Adds a slide bar to the gui for integers to the gui - * @param caption The text to display - * @param value The value to map to - * @param min The minimum value - * @param max The maximum value - * @returns True if adding item was successful - */ - bool slider_int(const std::string &caption, int32_t *value, int32_t min, int32_t max); - - /** - * @brief Adds a multiple choice drop box to the gui - * @param caption The text to display - * @param itemindex The item index to display - * @param items The items to display in the box - * @returns True if adding item was successful - */ - bool combo_box(const std::string &caption, int32_t *itemindex, std::vector items); - - /** - * @brief Adds a clickable button to the gui - * @param caption The text to display - * @returns True if adding item was successful - */ - bool button(const std::string &caption); - - /** - * @brief Adds a label to the gui - * @param formatstr The format string - */ - void text(const char *formatstr, ...); - - /** - * @brief Adds a color edit to the gui - * @tparam OP Mode of the color element. - * @tparam N Color channel count. Must be 3 or 4. - * @param caption The text to display - * @param color Color channel array on which the picker works. It contains values ranging from 0 to 1. - * @param width Element width. Zero is a special value for the default element width. - * @param flags Flags to modify the appearance and behavior of the element. - */ - template - bool color_op(const std::string &caption, std::array &color, float width = 0.0f, ImGuiColorEditFlags flags = 0) - { - static_assert((N == 3) || (N == 4), "The channel count must be 3 or 4."); - - ImGui::PushItemWidth(width); - bool res = color_op_impl(caption.c_str(), color.data(), flags); - ImGui::PopItemWidth(); - if (res) - dirty = true; - return res; - } - - private: - template - inline bool color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags) - { - assert(false); - return false; - } - - bool dirty = false; -}; - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - -template <> -bool HPPDrawer::color_op_impl(const char *caption, float *colors, ImGuiColorEditFlags flags); - class HPPVulkanSample; /** @@ -360,7 +212,7 @@ class HPPGui */ const StatsView &get_stats_view() const; - HPPDrawer &get_drawer(); + Drawer &get_drawer(); HPPFont const &get_font(const std::string &font_name = HPPGui::default_font) const; @@ -413,7 +265,7 @@ class HPPGui float content_scale_factor = 1.0f; // Scale factor to apply due to a difference between the window and GL pixel sizes float dpi_factor = 1.0f; // Scale factor to apply to the size of gui elements (expressed in dp) bool explicit_update = false; - HPPDrawer drawer; + Drawer drawer; std::vector fonts; std::unique_ptr font_image; std::unique_ptr font_image_view; diff --git a/framework/hpp_vulkan_sample.cpp b/framework/hpp_vulkan_sample.cpp index bbfe28a6bd..03fe1c4ac6 100644 --- a/framework/hpp_vulkan_sample.cpp +++ b/framework/hpp_vulkan_sample.cpp @@ -434,6 +434,13 @@ void HPPVulkanSample::input_event(const InputEvent &input_event) } } +Drawer *HPPVulkanSample::get_drawer() +{ + if (nullptr == gui) + return nullptr; + return &gui->get_drawer(); +} + void HPPVulkanSample::finish() { vkb::Application::finish(); @@ -492,6 +499,16 @@ void HPPVulkanSample::update_debug_window() } } +const std::map>> &HPPVulkanSample::get_available_shaders() const +{ + return reinterpret_cast>> const &>(Application::get_available_shaders()); +} + +void HPPVulkanSample::store_shaders(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders) +{ + Application::store_shaders(shader_language, reinterpret_cast> const &>(list_of_shaders)); +} + void HPPVulkanSample::set_viewport_and_scissor(vkb::core::HPPCommandBuffer const &command_buffer, const vk::Extent2D &extent) { command_buffer.get_handle().setViewport(0, {{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}}); diff --git a/framework/hpp_vulkan_sample.h b/framework/hpp_vulkan_sample.h index 780092652b..56b8177924 100644 --- a/framework/hpp_vulkan_sample.h +++ b/framework/hpp_vulkan_sample.h @@ -57,6 +57,11 @@ class HPPVulkanSample : public vkb::Application void input_event(const InputEvent &input_event) override; + /** + * @brief Returns the drawer object for the sample + */ + vkb::Drawer *get_drawer() override; + void finish() override; /** @@ -229,6 +234,18 @@ class HPPVulkanSample : public vkb::Application */ virtual void update_debug_window(); + /** + * @brief Returns stored shaders by sample + */ + const std::map>> &get_available_shaders() const; + + /** + * @brief Stores a list of shaders for the active sample, used by plugins to dynamically change the shader + * @param shader_language The shader language for which the shader list will be provided + * @param list_of_shaders The shader list, where paths and shader types are provided + */ + void store_shaders(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders); + /** * @brief Set viewport and scissor state in command buffer for a given extent */ diff --git a/framework/platform/application.cpp b/framework/platform/application.cpp index a4f0c0cef8..9d625e6807 100644 --- a/framework/platform/application.cpp +++ b/framework/platform/application.cpp @@ -54,21 +54,19 @@ void Application::input_event(const InputEvent &input_event) { } -void Application::update(float delta_time) +Drawer *Application::get_drawer() { - fps = 1.0f / delta_time; - frame_time = delta_time * 1000.0f; + return nullptr; } - -void Application::update_overlay(float delta_time, const std::function& additional_ui) +void Application::update(float delta_time) { - + fps = 1.0f / delta_time; + frame_time = delta_time * 1000.0f; } -void Application::change_shader(const vkb::ShaderSourceLanguage& shader_language, const std::vector>& shaders_path) +void Application::update_overlay(float delta_time, const std::function &additional_ui) { - } const std::string &Application::get_name() const @@ -86,13 +84,19 @@ DebugInfo &Application::get_debug_info() return debug_info; } -std::weak_ptr Application::get_gui() +void Application::change_shader(const vkb::ShaderSourceLanguage &shader_language) { - return gui; + LOGE("Not implemented by sample"); } -std::map>>& Application::get_available_shaders() +const std::map>> &Application::get_available_shaders() const { return available_shaders; } + +void Application::store_shaders(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders) +{ + available_shaders.insert({shader_language, list_of_shaders}); +} + } // namespace vkb diff --git a/framework/platform/application.h b/framework/platform/application.h index cc3500f302..3cdc04a257 100644 --- a/framework/platform/application.h +++ b/framework/platform/application.h @@ -58,15 +58,9 @@ class Application * @param delta_time The time taken since the last frame * @param additional_ui Function that implements an additional Gui */ - virtual void update_overlay(float delta_time, const std::function& additional_ui = [](){}); + virtual void update_overlay( + float delta_time, const std::function &additional_ui = []() {}); - /** - * @brief Indicates that the plugin wants to change the shader in the sample - * - * @param shader_language language the shader uses - * @param shaders_path sample type and path to it - */ - virtual void change_shader(const vkb::ShaderSourceLanguage& shader_language, const std::vector>& shaders_path); /** * @brief Handles cleaning up the application */ @@ -85,6 +79,11 @@ class Application */ virtual void input_event(const InputEvent &input_event); + /** + * @brief Returns the drawer object for the sample + */ + virtual Drawer *get_drawer(); + const std::string &get_name() const; void set_name(const std::string &name); @@ -103,11 +102,25 @@ class Application requested_close = true; } - std::weak_ptr get_gui(); + /** + * @brief Indicates that the plugin wants to change the shader in the sample + * @param shader_language language the shader uses + */ + virtual void change_shader(const vkb::ShaderSourceLanguage &shader_language); - std::map>>& get_available_shaders(); + /** + * @brief Returns stored shaders by sample + */ + const std::map>> &get_available_shaders() const; protected: + /** + * @brief Stores a list of shaders for the active sample, used by plugins to dynamically change the shader + * @param shader_language The shader language for which the shader list will be provided + * @param list_of_shaders The shader list, where paths and shader types are provided + */ + void store_shaders(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders); + float fps{0.0f}; float frame_time{0.0f}; // In ms @@ -120,15 +133,13 @@ class Application Window *window{nullptr}; - std::shared_ptr gui{nullptr}; - private: std::string name{}; /** * @brief stores the names of the shaders the sample uses */ - std::map>> available_shaders; + std::map>> available_shaders; // The debug info of the app DebugInfo debug_info{}; diff --git a/framework/platform/platform.cpp b/framework/platform/platform.cpp index c5ea93f340..6b61f82b83 100644 --- a/framework/platform/platform.cpp +++ b/framework/platform/platform.cpp @@ -199,7 +199,7 @@ void Platform::update() } active_app->update_overlay(delta_time, [=]() { - on_update_ui_overlay(gui.lock()->get_drawer()); + on_update_ui_overlay(*active_app->get_drawer()); }); active_app->update(delta_time); @@ -292,11 +292,6 @@ void Platform::set_window_properties(const Window::OptionalProperties &propertie window_properties.extent.height = properties.extent.height.has_value() ? properties.extent.height.value() : window_properties.extent.height; } -std::map>>& Platform::get_available_shaders() -{ - return get_app().get_available_shaders(); -} - const std::string &Platform::get_external_storage_directory() { return external_storage_directory; @@ -378,7 +373,6 @@ bool Platform::start_app() return false; } - gui = active_app->get_gui(); on_app_start(requested_app_info->id); return true; diff --git a/framework/platform/platform.h b/framework/platform/platform.h index 2b86c7e01a..6d32112cc4 100644 --- a/framework/platform/platform.h +++ b/framework/platform/platform.h @@ -17,10 +17,10 @@ #pragma once +#include #include #include #include -#include #include @@ -132,8 +132,6 @@ class Platform void on_post_draw(RenderContext &context); - std::map>>& get_available_shaders(); - static const uint32_t MIN_WINDOW_WIDTH; static const uint32_t MIN_WINDOW_HEIGHT; @@ -148,8 +146,6 @@ class Platform std::unique_ptr active_app{nullptr}; - std::weak_ptr gui; - virtual std::vector get_platform_sinks(); /** diff --git a/framework/platform/plugins/plugin.h b/framework/platform/plugins/plugin.h index 901945f5e2..3474693b79 100644 --- a/framework/platform/plugins/plugin.h +++ b/framework/platform/plugins/plugin.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2020-2021, Arm Limited and Contributors +/* Copyright (c) 2020-2023, Arm Limited and Contributors + * Copyright (c) 2023, Mobica Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -35,10 +36,10 @@ class Plugin; * @brief Tags are used to define a plugins behaviour. This is useful to dictate which plugins will work together * and which will not without directly specifying an exclusion or inclusion list. Tags are struct types so that they can * be used in the tagging system (See plugin implementation). - * + * * Entrypoint - An entrypoint is a starting point for the application that will load a vkb::Application (see start_app) * FullControl - The plugin wants full control over how the application executes. Stopping plugins will be ignored (see batch_mode) - * Stopping - The plugin will stop the app through its own mechanism (see stop_after) + * Stopping - The plugin will stop the app through its own mechanism (see stop_after) * Passive - These plugins provide non intrusive behaviour (see fps_logger) */ namespace tags @@ -55,7 +56,7 @@ struct Passive /** * @brief Associate how plugins can interact with each other. This interoperability is decided by comparing tags of different plugins. The plugins inclusion and exclusion lists are populated by this function - * + * * @param plugins A list of plugins which are used together * @return std::vector A list of plugins which are used together */ @@ -63,7 +64,7 @@ std::vector associate_plugins(const std::vector &plugins); /** * @brief Hooks are points in the project that an plugin can subscribe too. These can be expanded on to implement more behaviour in the future - * + * * Update - Executed at each update() loop * OnAppStart - Executed when an app starts * OnAppClose - Executed when an app closes @@ -93,7 +94,7 @@ class Plugin /** * @brief Conducts the process of activating and initializing an plugin - * + * * @param platform The platform * @param parser The parser used to check if the plugins flags are present * @param force_activation Force a plugin to be activated, not advised unless the plugin works without inputs @@ -106,35 +107,35 @@ class Plugin /** * @brief Return a list of hooks that an plugin wants to subscribe to - * + * * @return Hooks that the plugin wants to use */ virtual const std::vector &get_hooks() const = 0; /** * @brief Called when an application has been updated - * + * * @param delta_time The time taken to compute a frame */ virtual void on_update(float delta_time) = 0; /** * @brief Called when an app has started - * + * * @param app_id The ID of the app */ virtual void on_app_start(const std::string &app_id) = 0; /** * @brief Called when an app has been closed - * + * * @param app_id The ID of the app */ virtual void on_app_close(const std::string &app_id) = 0; /** * @brief Handle when an application errors - * + * * @param app_id The ID of the app which errored */ virtual void on_app_error(const std::string &app_id) = 0; @@ -151,13 +152,13 @@ class Plugin /** * @brief Allows to add a UI to a sample - * + * * @param drawer The object that is responsible for drawing the overlay */ virtual void on_update_ui_overlay(vkb::Drawer &drawer) = 0; - const std::string & get_name() const; - const std::string & get_description() const; + const std::string &get_name() const; + const std::string &get_description() const; void excludes(Plugin *plugin); const std::vector &get_exclusions() const; void includes(Plugin *plugin); @@ -165,7 +166,7 @@ class Plugin /** * @brief Test whether the plugin contains a given tag - * + * * @tparam C the tag to check for * @return true tag present * @return false tag not present @@ -178,7 +179,7 @@ class Plugin /** * @brief Tests whether the plugins contains multiple tags - * + * * @tparam C A set of tags * @return true Contains all tags * @return false Does not contain all tags @@ -197,7 +198,7 @@ class Plugin /** * @brief Implemented by plugin base to return if the plugin contains a tag - * + * * @param id The tag id of a tag * @return true contains tag * @return false does not contain tag @@ -207,7 +208,7 @@ class Plugin protected: /** * @brief An plugin will override this method so that it can check if it will be activated - * + * * @param parser A parser that has parsed the command line arguments when the app starts * @return true If the plugin should be activated * @return false If the plugin should be ignored @@ -216,7 +217,7 @@ class Plugin /** * @brief Sets up an plugin by using values from the parser - * + * * @param parser The parser */ virtual void init(const CommandParser &parser) = 0; @@ -239,7 +240,7 @@ namespace plugins /** * @brief Get all plugins with tags * Plugin must include one or more tags - * + * * @tparam TAGS Tags that an plugin must contain * @param domain The list of plugins to query * @return const std::vector A list of plugins containing one or more TAGS @@ -271,7 +272,7 @@ const std::vector with_tags(const std::vector &domain = {}) * @brief Get all plugins without the given tags * Plugin must not include one or more tags * Essentially the opoposite of plugins::with_tags<...TAGS>() - * + * * @tparam TAGS Tags that an plugin must not contain * @param domain The list of plugins to query * @return const std::vector A list of plugins containing one or more TAGS diff --git a/framework/platform/plugins/plugin_base.h b/framework/platform/plugins/plugin_base.h index 47c20f00a0..771de11661 100644 --- a/framework/platform/plugins/plugin_base.h +++ b/framework/platform/plugins/plugin_base.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2020-2021, Arm Limited and Contributors +/* Copyright (c) 2020-2023, Arm Limited and Contributors + * Copyright (c) 2023, Mobica Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -27,7 +28,7 @@ namespace vkb { /** * @brief PluginBase is the base class that plugins inherit from. The class enforces the use of tags when creating new plugins. - * For method information see Plugin + * For method information see Plugin */ template class PluginBase : public Plugin, public Tag @@ -38,7 +39,7 @@ class PluginBase : public Plugin, public Tag virtual ~PluginBase() = default; virtual const std::vector &get_cli_commands() const override; - virtual const std::vector & get_hooks() const override; + virtual const std::vector &get_hooks() const override; virtual bool has_tag(TagID id) const override; // hooks that can be implemented by plugins diff --git a/framework/vulkan_sample.cpp b/framework/vulkan_sample.cpp index 1393356c6d..f9703c8f69 100644 --- a/framework/vulkan_sample.cpp +++ b/framework/vulkan_sample.cpp @@ -333,7 +333,7 @@ void VulkanSample::update(float delta_time) render_context->submit(command_buffer); } -void VulkanSample::update_overlay(float delta_time, const std::function& additional_ui) +void VulkanSample::update_overlay(float delta_time, const std::function &additional_ui) { } @@ -478,6 +478,13 @@ void VulkanSample::input_event(const InputEvent &input_event) } } +Drawer *VulkanSample::get_drawer() +{ + if (nullptr == gui) + return nullptr; + return &gui->get_drawer(); +} + void VulkanSample::finish() { Application::finish(); @@ -498,11 +505,6 @@ Configuration &VulkanSample::get_configuration() return configuration; } -void VulkanSample::change_shader(const vkb::ShaderSourceLanguage& shader_language, const std::vector>& shaders_path) -{ - LOGE("Not implemented by sample"); -} - void VulkanSample::draw_gui() { } diff --git a/framework/vulkan_sample.h b/framework/vulkan_sample.h index 87dfdef610..ba52bd9016 100644 --- a/framework/vulkan_sample.h +++ b/framework/vulkan_sample.h @@ -132,20 +132,18 @@ class VulkanSample : public Application * @param delta_time The time taken since the last frame * @param additional_ui Function that implements an additional Gui */ - virtual void update_overlay(float delta_time, const std::function& additional_ui = [](){}) override; + virtual void update_overlay( + float delta_time, const std::function &additional_ui = []() {}) override; - /** - * @brief Indicates that the plugin wants to change the shader in the sample - * - * @param shader_language language the shader uses - * @param shaders_path sample type and path to it - */ - virtual void change_shader(const vkb::ShaderSourceLanguage& shader_language, const std::vector>& shaders_path) override; - bool resize(uint32_t width, uint32_t height) override; void input_event(const InputEvent &input_event) override; + /** + * @brief Returns the drawer object for the sample + */ + vkb::Drawer *get_drawer() override; + void finish() override; /** @@ -202,6 +200,8 @@ class VulkanSample : public Application */ std::unique_ptr scene{nullptr}; + std::unique_ptr gui{nullptr}; + std::unique_ptr stats{nullptr}; /** diff --git a/samples/api/dynamic_uniform_buffers/CMakeLists.txt b/samples/api/dynamic_uniform_buffers/CMakeLists.txt index 4307bf2ca1..1dfe4f92b1 100644 --- a/samples/api/dynamic_uniform_buffers/CMakeLists.txt +++ b/samples/api/dynamic_uniform_buffers/CMakeLists.txt @@ -1,7 +1,8 @@ -# Copyright (c) 2019-2021, Sascha Willems +# Copyright (c) 2019-2023, Sascha Willems +# Copyright (c) 2023, Mobica Limited # # SPDX-License-Identifier: Apache-2.0 -# +# # Licensed under the Apache License, Version 2.0 the "License"; # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.cpp b/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.cpp index a65517e615..afcf0193b7 100644 --- a/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.cpp +++ b/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.cpp @@ -289,7 +289,7 @@ void DynamicUniformBuffers::setup_descriptor_set() vkUpdateDescriptorSets(get_device().get_handle(), static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); } -void DynamicUniformBuffers::prepare_pipelines() +void DynamicUniformBuffers::prepare_pipelines(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders) { VkPipelineInputAssemblyStateCreateInfo input_assembly_state = vkb::initializers::pipeline_input_assembly_state_create_info( @@ -339,10 +339,11 @@ void DynamicUniformBuffers::prepare_pipelines() 0); // Load shaders - std::array shader_stages; - - shader_stages[0] = load_shader("dynamic_uniform_buffers/base.vert", VK_SHADER_STAGE_VERTEX_BIT); - shader_stages[1] = load_shader("dynamic_uniform_buffers/base.frag", VK_SHADER_STAGE_FRAGMENT_BIT); + std::vector shader_stages; + for (auto &shader : list_of_shaders) + { + shader_stages.emplace_back(load_shader(shader.second, shader.first, shader_language)); + } // Vertex bindings and attributes const std::vector vertex_input_bindings = { @@ -500,21 +501,29 @@ bool DynamicUniformBuffers::prepare(const vkb::ApplicationOptions &options) // Note: Using reversed depth-buffer for increased precision, so Znear and Zfar are flipped camera.set_perspective(60.0f, static_cast(width) / static_cast(height), 256.0f, 0.1f); + std::vector>>> supported_shaders{ + {vkb::ShaderSourceLanguage::GLSL, { + {VK_SHADER_STAGE_VERTEX_BIT, "dynamic_uniform_buffers/base.vert"}, + {VK_SHADER_STAGE_FRAGMENT_BIT, "dynamic_uniform_buffers/base.frag"}, + }}, + + {vkb::ShaderSourceLanguage::SPV, { + {VK_SHADER_STAGE_VERTEX_BIT, "dynamic_uniform_buffers/base.vert.spv"}, + {VK_SHADER_STAGE_FRAGMENT_BIT, "dynamic_uniform_buffers/base.frag.spv"}, + }}}; + for (auto &shader : supported_shaders) + { + store_shaders(shader.first, shader.second); + } + generate_cube(); prepare_uniform_buffers(); setup_descriptor_set_layout(); - prepare_pipelines(); + prepare_pipelines(supported_shaders.begin()->first, supported_shaders.begin()->second); setup_descriptor_pool(); setup_descriptor_set(); build_command_buffers(); - store_shader(vkb::ShaderSourceLanguage::VK_GLSL, { - {vkb::ShaderType::VERT, "dynamic_uniform_buffers/base.vert"}, - {vkb::ShaderType::FRAG, "dynamic_uniform_buffers/base.frag"}, - } ); - store_shader(vkb::ShaderSourceLanguage::VK_SPV, { - {vkb::ShaderType::VERT, "dynamic_uniform_buffers/base.vert.spv"}, - {vkb::ShaderType::FRAG, "dynamic_uniform_buffers/base.frag.spv"}, - } ); + prepared = true; return true; } @@ -526,9 +535,10 @@ bool DynamicUniformBuffers::resize(const uint32_t width, const uint32_t height) return true; } -void DynamicUniformBuffers::change_shader(const vkb::ShaderSourceLanguage& shader_language, const std::vector>& shaders_path) +void DynamicUniformBuffers::change_shader(const vkb::ShaderSourceLanguage &shader_language) { - + vkDestroyPipeline(get_device().get_handle(), pipeline, nullptr); + prepare_pipelines(shader_language, get_available_shaders().find(shader_language)->second); } void DynamicUniformBuffers::render(float delta_time) diff --git a/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.h b/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.h index 96a19c3952..646dda2e91 100644 --- a/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.h +++ b/samples/api/dynamic_uniform_buffers/dynamic_uniform_buffers.h @@ -88,7 +88,7 @@ class DynamicUniformBuffers : public ApiVulkanSample void setup_descriptor_pool(); void setup_descriptor_set_layout(); void setup_descriptor_set(); - void prepare_pipelines(); + void prepare_pipelines(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders); void prepare_uniform_buffers(); void update_uniform_buffers(); void update_dynamic_uniform_buffer(float delta_time, bool force = false); @@ -96,7 +96,7 @@ class DynamicUniformBuffers : public ApiVulkanSample bool prepare(const vkb::ApplicationOptions &options) override; virtual void render(float delta_time) override; virtual bool resize(const uint32_t width, const uint32_t height) override; - virtual void change_shader(const vkb::ShaderSourceLanguage& shader_language, const std::vector>& shaders_path) override; + virtual void change_shader(const vkb::ShaderSourceLanguage &shader_language) override; }; std::unique_ptr create_dynamic_uniform_buffers(); diff --git a/samples/api/hpp_dynamic_uniform_buffers/CMakeLists.txt b/samples/api/hpp_dynamic_uniform_buffers/CMakeLists.txt index 5a3d338c11..d835578a0e 100644 --- a/samples/api/hpp_dynamic_uniform_buffers/CMakeLists.txt +++ b/samples/api/hpp_dynamic_uniform_buffers/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (c) 2021-2023, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2023, Mobica Limited # # SPDX-License-Identifier: Apache-2.0 # @@ -27,4 +28,6 @@ add_sample_with_tags( DESCRIPTION "Demonstrates the use of dynamic offsets into one single uniform buffers for rendering multiple objects, using vulkan.hpp" SHADER_FILES_GLSL "dynamic_uniform_buffers/base.vert" - "dynamic_uniform_buffers/base.frag") \ No newline at end of file + "dynamic_uniform_buffers/base.frag" + "dynamic_uniform_buffers/base.vert.spv" + "dynamic_uniform_buffers/base.frag.spv") \ No newline at end of file diff --git a/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.cpp b/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.cpp index 8b82a9ad6c..b550fec476 100644 --- a/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.cpp +++ b/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.cpp @@ -90,6 +90,21 @@ bool HPPDynamicUniformBuffers::prepare(const vkb::ApplicationOptions &options) vk::Device device = get_device()->get_handle(); + std::vector>>> supported_shaders{ + {vkb::ShaderSourceLanguage::GLSL, { + {vk::ShaderStageFlagBits::eVertex, "dynamic_uniform_buffers/base.vert"}, + {vk::ShaderStageFlagBits::eFragment, "dynamic_uniform_buffers/base.frag"}, + }}, + + {vkb::ShaderSourceLanguage::SPV, { + {vk::ShaderStageFlagBits::eVertex, "dynamic_uniform_buffers/base.vert.spv"}, + {vk::ShaderStageFlagBits::eFragment, "dynamic_uniform_buffers/base.frag.spv"}, + }}}; + for (auto &shader : supported_shaders) + { + store_shaders(shader.first, shader.second); + } + prepare_camera(); generate_cube(); prepare_uniform_buffers(); @@ -100,7 +115,7 @@ bool HPPDynamicUniformBuffers::prepare(const vkb::ApplicationOptions &options) descriptor_set_layout = device.createDescriptorSetLayout({{}, bindings}); pipeline_layout = device.createPipelineLayout({{}, descriptor_set_layout}); - create_pipeline(); + create_pipeline(supported_shaders.begin()->first, supported_shaders.begin()->second); // Example uses one ubo, on dynamic ubo, and one combined image sampler std::array pool_sizes = {{{vk::DescriptorType::eUniformBuffer, 1}, @@ -123,6 +138,12 @@ bool HPPDynamicUniformBuffers::resize(const uint32_t width, const uint32_t heigh return true; } +void HPPDynamicUniformBuffers::change_shader(const vkb::ShaderSourceLanguage &shader_language) +{ + get_device()->get_handle().destroyPipeline(pipeline); + create_pipeline(shader_language, get_available_shaders().find(shader_language)->second); +} + void HPPDynamicUniformBuffers::build_command_buffers() { vk::DeviceSize offset = 0; @@ -178,12 +199,14 @@ void HPPDynamicUniformBuffers::render(float delta_time) } } -void HPPDynamicUniformBuffers::create_pipeline() +void HPPDynamicUniformBuffers::create_pipeline(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders) { // Load shaders - std::array shader_stages = {{load_shader("dynamic_uniform_buffers/base.vert", vk::ShaderStageFlagBits::eVertex), - load_shader("dynamic_uniform_buffers/base.frag", - vk::ShaderStageFlagBits::eFragment)}}; + std::vector shader_stages; + for (auto &shader : list_of_shaders) + { + shader_stages.emplace_back(load_shader(shader.second, shader.first, shader_language)); + } // Vertex bindings and attributes vk::VertexInputBindingDescription vertex_input_binding(0, sizeof(Vertex), vk::VertexInputRate::eVertex); diff --git a/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.h b/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.h index dd904793ad..825550a1b5 100644 --- a/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.h +++ b/samples/api/hpp_dynamic_uniform_buffers/hpp_dynamic_uniform_buffers.h @@ -72,12 +72,13 @@ class HPPDynamicUniformBuffers : public HPPApiVulkanSample private: bool prepare(const vkb::ApplicationOptions &options) override; bool resize(const uint32_t width, const uint32_t height) override; + void change_shader(const vkb::ShaderSourceLanguage &shader_language) override; // from HPPApiVulkanSample void render(float delta_time) override; void build_command_buffers() override; - void create_pipeline(); + void create_pipeline(const vkb::ShaderSourceLanguage &shader_language, const std::vector> &list_of_shaders); void draw(); void generate_cube(); void prepare_camera(); diff --git a/samples/api/hpp_hdr/hpp_hdr.cpp b/samples/api/hpp_hdr/hpp_hdr.cpp index 069f1776d6..f12130ca47 100644 --- a/samples/api/hpp_hdr/hpp_hdr.cpp +++ b/samples/api/hpp_hdr/hpp_hdr.cpp @@ -186,7 +186,7 @@ void HPPHDR::build_command_buffers() } } -void HPPHDR::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPHDR::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Settings")) { diff --git a/samples/api/hpp_hdr/hpp_hdr.h b/samples/api/hpp_hdr/hpp_hdr.h index 2cff1f7da1..f27199692a 100644 --- a/samples/api/hpp_hdr/hpp_hdr.h +++ b/samples/api/hpp_hdr/hpp_hdr.h @@ -186,7 +186,7 @@ class HPPHDR : public HPPApiVulkanSample // from HPPApiVulkanSample virtual void build_command_buffers() override; - virtual void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + virtual void on_update_ui_overlay(vkb::Drawer &drawer) override; virtual void render(float delta_time) override; vk::DeviceMemory allocate_memory(vk::Image image); diff --git a/samples/api/hpp_instancing/hpp_instancing.cpp b/samples/api/hpp_instancing/hpp_instancing.cpp index 640daf680d..d23d1410ed 100644 --- a/samples/api/hpp_instancing/hpp_instancing.cpp +++ b/samples/api/hpp_instancing/hpp_instancing.cpp @@ -461,7 +461,7 @@ void HPPInstancing::render(float delta_time) } } -void HPPInstancing::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPInstancing::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Statistics")) { diff --git a/samples/api/hpp_instancing/hpp_instancing.h b/samples/api/hpp_instancing/hpp_instancing.h index 7e23d284dd..9fc4b4ea7a 100644 --- a/samples/api/hpp_instancing/hpp_instancing.h +++ b/samples/api/hpp_instancing/hpp_instancing.h @@ -102,7 +102,7 @@ class HPPInstancing : public HPPApiVulkanSample // from HPPApiVulkanSample void build_command_buffers() override; - void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + void on_update_ui_overlay(vkb::Drawer &drawer) override; void render(float delta_time) override; void draw(); diff --git a/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.cpp b/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.cpp index 785a46769e..350e9c22c9 100644 --- a/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.cpp +++ b/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.cpp @@ -122,7 +122,7 @@ void HPPSeparateImageSampler::build_command_buffers() } } -void HPPSeparateImageSampler::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPSeparateImageSampler::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Settings")) { diff --git a/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.h b/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.h index fd7c830d6f..919ed7992b 100644 --- a/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.h +++ b/samples/api/hpp_separate_image_sampler/hpp_separate_image_sampler.h @@ -53,7 +53,7 @@ class HPPSeparateImageSampler : public HPPApiVulkanSample // from HPPApiVulkanSample void build_command_buffers() override; - void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + void on_update_ui_overlay(vkb::Drawer &drawer) override; void render(float delta_time) override; void view_changed() override; diff --git a/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.cpp b/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.cpp index 5483cb2047..e82b5e5cab 100644 --- a/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.cpp +++ b/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.cpp @@ -175,7 +175,7 @@ void HPPTerrainTessellation::build_command_buffers() } } -void HPPTerrainTessellation::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPTerrainTessellation::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Settings")) { diff --git a/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.h b/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.h index d6cc5c670e..3c20238605 100644 --- a/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.h +++ b/samples/api/hpp_terrain_tessellation/hpp_terrain_tessellation.h @@ -119,7 +119,7 @@ class HPPTerrainTessellation : public HPPApiVulkanSample // from HPPApiVulkanSample void build_command_buffers() override; - void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + void on_update_ui_overlay(vkb::Drawer &drawer) override; void render(float delta_time) override; void view_changed() override; diff --git a/samples/api/hpp_texture_loading/hpp_texture_loading.cpp b/samples/api/hpp_texture_loading/hpp_texture_loading.cpp index 5123d4e3f5..130cc528b1 100644 --- a/samples/api/hpp_texture_loading/hpp_texture_loading.cpp +++ b/samples/api/hpp_texture_loading/hpp_texture_loading.cpp @@ -620,7 +620,7 @@ void HPPTextureLoading::view_changed() update_uniform_buffers(); } -void HPPTextureLoading::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPTextureLoading::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Settings")) { diff --git a/samples/api/hpp_texture_loading/hpp_texture_loading.h b/samples/api/hpp_texture_loading/hpp_texture_loading.h index 6d3d58f8b9..093e340d50 100644 --- a/samples/api/hpp_texture_loading/hpp_texture_loading.h +++ b/samples/api/hpp_texture_loading/hpp_texture_loading.h @@ -85,7 +85,7 @@ class HPPTextureLoading : public HPPApiVulkanSample bool prepare(const vkb::ApplicationOptions &options) override; virtual void render(float delta_time) override; virtual void view_changed() override; - virtual void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + virtual void on_update_ui_overlay(vkb::Drawer &drawer) override; }; std::unique_ptr create_hpp_texture_loading(); diff --git a/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.cpp b/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.cpp index 9feeffea1b..99d37ca444 100644 --- a/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.cpp +++ b/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.cpp @@ -117,7 +117,7 @@ void HPPTextureMipMapGeneration::build_command_buffers() } } -void HPPTextureMipMapGeneration::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPTextureMipMapGeneration::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Settings")) { diff --git a/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.h b/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.h index 8784753243..a5dbc49b9d 100644 --- a/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.h +++ b/samples/api/hpp_texture_mipmap_generation/hpp_texture_mipmap_generation.h @@ -56,7 +56,7 @@ class HPPTextureMipMapGeneration : public HPPApiVulkanSample // from HPPApiVulkanSample void build_command_buffers() override; - void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + void on_update_ui_overlay(vkb::Drawer &drawer) override; void render(float delta_time) override; void view_changed() override; diff --git a/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.cpp b/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.cpp index c2d7470646..5177a4632c 100644 --- a/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.cpp +++ b/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.cpp @@ -264,7 +264,7 @@ void HPPTimestampQueries::build_command_buffers() } } -void HPPTimestampQueries::on_update_ui_overlay(vkb::HPPDrawer &drawer) +void HPPTimestampQueries::on_update_ui_overlay(vkb::Drawer &drawer) { if (drawer.header("Settings")) { diff --git a/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.h b/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.h index 5a773796b9..c548be6b1a 100644 --- a/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.h +++ b/samples/api/hpp_timestamp_queries/hpp_timestamp_queries.h @@ -136,7 +136,7 @@ class HPPTimestampQueries : public HPPApiVulkanSample // from HPPApiVulkanSample void build_command_buffers() override; - void on_update_ui_overlay(vkb::HPPDrawer &drawer) override; + void on_update_ui_overlay(vkb::Drawer &drawer) override; void render(float delta_time) override; void create_attachment(vk::Format format, vk::ImageUsageFlagBits usage, FramebufferAttachment *attachment); diff --git a/shaders/dynamic_uniform_buffers/base.frag.spv b/shaders/dynamic_uniform_buffers/base.frag.spv index 61fd9cc248..aa4e796ca7 100644 Binary files a/shaders/dynamic_uniform_buffers/base.frag.spv and b/shaders/dynamic_uniform_buffers/base.frag.spv differ