forked from KhronosGroup/Vulkan-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gui.h
331 lines (253 loc) · 7.85 KB
/
gui.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
/* Copyright (c) 2018-2024, Arm Limited and Contributors
* Copyright (c) 2019-2024, Sascha Willems
*
* 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 <cstdint>
#include <functional>
#include <future>
#include <imgui.h>
#include <imgui_internal.h>
#include <thread>
#include "core/buffer.h"
#include "core/command_buffer.h"
#include "core/sampler.h"
#include "debug_info.h"
#include "drawer.h"
#include "filesystem/legacy.h"
#include "platform/input_events.h"
#include "rendering/render_context.h"
#include "stats/stats.h"
#include "vulkan_sample.h"
namespace vkb
{
class Window;
/**
* @brief Helper structure for fonts loaded from TTF
*/
struct Font
{
/**
* @brief Constructor
* @param name The name of the font file that exists within 'assets/fonts' (without extension)
* @param size The font size, scaled by DPI
*/
Font(const std::string &name, float size) :
name{name},
data{vkb::fs::read_asset("fonts/" + name + ".ttf")},
size{size}
{
// Keep ownership of the font data to avoid a double delete
ImFontConfig font_config{};
font_config.FontDataOwnedByAtlas = false;
if (size < 1.0f)
{
size = 20.0f;
}
ImGuiIO &io = ImGui::GetIO();
handle = io.Fonts->AddFontFromMemoryTTF(data.data(), static_cast<int>(data.size()), size, &font_config);
}
ImFont *handle{nullptr};
std::string name;
std::vector<uint8_t> data;
float size{};
};
/**
* @brief Vulkan helper class for Dear ImGui
*/
class Gui
{
public:
/**
* @brief Helper class for drawing statistics
*/
class StatsView
{
public:
/**
* @brief Constructs a StatsView
* @param stats Const pointer to the Stats data object; may be null
*/
StatsView(const Stats *stats);
/**
* @brief Resets the max values for the stats
* which do not have a fixed max
*/
void reset_max_values();
/**
* @brief Resets the max value for a specific stat
*/
void reset_max_value(const StatIndex index);
std::map<StatIndex, StatGraphData> graph_map;
float graph_height{50.0f};
float top_padding{1.1f};
};
/**
* @brief Helper class for rendering debug statistics in the GUI
*/
class DebugView
{
public:
bool active{false};
float scale{1.7f};
uint32_t max_fields{8};
float label_column_width{0};
};
// The name of the default font file to use
static const std::string default_font;
struct PushConstBlock
{
glm::vec2 scale;
glm::vec2 translate;
} push_const_block;
/// Used to show/hide the GUI
static bool visible;
/**
* @brief Initializes the Gui
* @param sample A vulkan render context
* @param window A Window object from which to draw DPI and content scaling information
* @param stats A statistics object (null if no statistics are used)
* @param font_size The font size
* @param explicit_update If true, update buffers every frame
*/
Gui(VulkanSampleC &sample, const Window &window, const Stats *stats = nullptr, const float font_size = 21.0f, bool explicit_update = false);
/**
* @brief Destroys the Gui
*/
~Gui();
void prepare(const VkPipelineCache pipeline_cache, const VkRenderPass render_pass, const std::vector<VkPipelineShaderStageCreateInfo> &shader_stages);
/**
* @brief Handles resizing of the window
* @param width New width of the window
* @param height New height of the window
*/
void resize(const uint32_t width, const uint32_t height) const;
/**
* @brief Starts a new ImGui frame
* to be called before drawing any window
*/
inline void new_frame();
/**
* @brief Updates the Gui
* @param delta_time Time passed since last update
*/
void update(const float delta_time);
bool update_buffers();
/**
* @brief Draws the Gui
* @param command_buffer Command buffer to register draw-commands
*/
void draw(CommandBuffer &command_buffer);
/**
* @brief Draws the Gui
* @param command_buffer Command buffer to register draw-commands
*/
void draw(VkCommandBuffer command_buffer);
/**
* @brief Shows an overlay top window with app info and maybe stats
* @param app_name Application name
* @param stats Statistics to show (can be null)
* @param debug_info Debug info to show (can be null)
*/
void show_top_window(const std::string &app_name, const Stats *stats = nullptr, DebugInfo *debug_info = nullptr);
/**
* @brief Shows the ImGui Demo window
*/
void show_demo_window();
/**
* @brief Shows an child with app info
* @param app_name Application name
*/
void show_app_info(const std::string &app_name);
/**
* @brief Shows a moveable window with debug information
* @param debug_info The object holding the data fields to be displayed
* @param position The absolute position to set
*/
void show_debug_window(DebugInfo &debug_info, const ImVec2 &position);
/**
* @brief Shows a child with statistics
* @param stats Statistics to show
*/
void show_stats(const Stats &stats);
/**
* @brief Shows an options windows, to be filled by the sample,
* which will be positioned at the top
* @param body ImGui commands defining the body of the window
* @param lines The number of lines of text to draw in the window
* These will help the gui to calculate the height of the window
*/
void show_options_window(std::function<void()> body, const uint32_t lines = 3);
void show_simple_window(const std::string &name, uint32_t last_fps, std::function<void()> body);
bool input_event(const InputEvent &input_event);
/**
* @return The stats view
*/
StatsView &get_stats_view();
Drawer &get_drawer();
Font &get_font(const std::string &font_name = Gui::default_font);
bool is_debug_view_active() const;
void set_subpass(const uint32_t subpass);
private:
/**
* @brief Block size of a buffer pool in kilobytes
*/
static constexpr uint32_t BUFFER_POOL_BLOCK_SIZE = 256;
/**
* @brief Updates Vulkan buffers
* @param frame Frame to render into
*/
void update_buffers(CommandBuffer &command_buffer, RenderFrame &render_frame);
static const double press_time_ms;
static const float overlay_alpha;
static const ImGuiWindowFlags common_flags;
static const ImGuiWindowFlags options_flags;
static const ImGuiWindowFlags info_flags;
VulkanSampleC &sample;
std::unique_ptr<vkb::core::BufferC> vertex_buffer;
std::unique_ptr<vkb::core::BufferC> index_buffer;
size_t last_vertex_buffer_size;
size_t last_index_buffer_size;
/// Scale factor to apply due to a difference between the window and GL pixel sizes
float content_scale_factor{1.0f};
/// Scale factor to apply to the size of gui elements (expressed in dp)
float dpi_factor{1.0f};
bool explicit_update{false};
Drawer drawer;
std::vector<Font> fonts;
std::unique_ptr<core::Image> font_image;
std::unique_ptr<core::ImageView> font_image_view;
std::unique_ptr<core::Sampler> sampler{nullptr};
PipelineLayout *pipeline_layout{nullptr};
StatsView stats_view;
DebugView debug_view;
VkDescriptorPool descriptor_pool{VK_NULL_HANDLE};
VkDescriptorSetLayout descriptor_set_layout{VK_NULL_HANDLE};
VkDescriptorSet descriptor_set{VK_NULL_HANDLE};
VkPipeline pipeline{VK_NULL_HANDLE};
/// Used to measure duration of input events
Timer timer;
bool prev_visible{true};
/// Whether or not the GUI has detected a multi touch gesture
bool two_finger_tap = false;
bool show_graph_file_output = false;
uint32_t subpass = 0;
};
void Gui::new_frame()
{
ImGui::NewFrame();
}
} // namespace vkb