Line |
Branch |
Exec |
Source |
1 |
|
|
// vulkan_guide.h : Include file for standard system include files, |
2 |
|
|
// or project specific include files. |
3 |
|
|
|
4 |
|
|
#pragma once |
5 |
|
|
|
6 |
|
|
#include <vk_mesh.h> |
7 |
|
|
#include <vk_types.h> |
8 |
|
|
|
9 |
|
|
#include <deque> |
10 |
|
|
#include <functional> |
11 |
|
|
#include <string> |
12 |
|
|
#include <unordered_map> |
13 |
|
|
#include <vector> |
14 |
|
|
|
15 |
|
|
#define IMGUI_DEFINE_MATH_OPERATORS |
16 |
|
|
#include <imgui.h> |
17 |
|
|
|
18 |
|
|
#include <SDL.h> |
19 |
|
|
#include <glm/glm.hpp> |
20 |
|
|
#include <glm/gtx/transform.hpp> |
21 |
|
|
|
22 |
|
|
struct Texture { |
23 |
|
|
AllocatedImage image; |
24 |
|
|
VkImageView imageView; |
25 |
|
|
int height; |
26 |
|
|
int width; |
27 |
|
|
}; |
28 |
|
|
|
29 |
|
|
class PipelineBuilder { |
30 |
|
|
public: |
31 |
|
|
std::vector<VkPipelineShaderStageCreateInfo> _shaderStages; |
32 |
|
|
VkPipelineVertexInputStateCreateInfo _vertexInputInfo; |
33 |
|
|
VkPipelineInputAssemblyStateCreateInfo _inputAssembly; |
34 |
|
|
VkViewport _viewport; |
35 |
|
|
VkRect2D _scissor; |
36 |
|
|
VkPipelineRasterizationStateCreateInfo _rasterizer; |
37 |
|
|
VkPipelineColorBlendAttachmentState _colorBlendAttachment; |
38 |
|
|
VkPipelineMultisampleStateCreateInfo _multisampling; |
39 |
|
|
VkPipelineLayout _pipelineLayout; |
40 |
|
|
VkPipelineDepthStencilStateCreateInfo _depthStencil; |
41 |
|
|
VkPipeline build_pipeline(VkDevice device, VkRenderPass pass); |
42 |
|
|
}; |
43 |
|
|
|
44 |
|
|
struct DeletionQueue { |
45 |
|
|
std::deque<std::function<void()>> deletors; |
46 |
|
|
|
47 |
|
|
void push_function(std::function<void()>&& function) { deletors.push_back(function); } |
48 |
|
|
|
49 |
|
|
void flush() { |
50 |
|
|
// reverse iterate the deletion queue to execute all the functions |
51 |
|
✗ |
for (auto it = deletors.rbegin(); it != deletors.rend(); it++) { |
52 |
|
✗ |
(*it)(); // call functors |
53 |
|
|
} |
54 |
|
|
|
55 |
|
✗ |
deletors.clear(); |
56 |
|
✗ |
} |
57 |
|
|
}; |
58 |
|
|
|
59 |
|
|
struct MeshPushConstants { |
60 |
|
|
glm::vec4 data; |
61 |
|
|
glm::mat4 render_matrix; |
62 |
|
|
}; |
63 |
|
|
|
64 |
|
|
struct Material { |
65 |
|
|
VkDescriptorSet textureSet{VK_NULL_HANDLE}; |
66 |
|
|
VkPipeline pipeline; |
67 |
|
|
VkPipelineLayout pipelineLayout; |
68 |
|
|
}; |
69 |
|
|
|
70 |
|
|
struct RenderObject { |
71 |
|
|
Mesh* mesh; |
72 |
|
|
|
73 |
|
|
Material* material; |
74 |
|
|
|
75 |
|
|
glm::mat4 transformMatrix; |
76 |
|
|
}; |
77 |
|
|
|
78 |
|
|
struct FrameData { |
79 |
|
|
VkSemaphore _presentSemaphore, _renderSemaphore; |
80 |
|
|
VkFence _renderFence; |
81 |
|
|
|
82 |
|
|
DeletionQueue _frameDeletionQueue; |
83 |
|
|
|
84 |
|
|
VkCommandPool _commandPool; |
85 |
|
|
VkCommandBuffer _mainCommandBuffer; |
86 |
|
|
|
87 |
|
|
AllocatedBuffer cameraBuffer; |
88 |
|
|
VkDescriptorSet globalDescriptor; |
89 |
|
|
|
90 |
|
|
AllocatedBuffer objectBuffer; |
91 |
|
|
VkDescriptorSet objectDescriptor; |
92 |
|
|
}; |
93 |
|
|
|
94 |
|
|
struct UploadContext { |
95 |
|
|
VkFence _uploadFence; |
96 |
|
|
VkCommandPool _commandPool; |
97 |
|
|
VkCommandBuffer _commandBuffer; |
98 |
|
|
}; |
99 |
|
|
struct GPUCameraData { |
100 |
|
|
glm::mat4 view; |
101 |
|
|
glm::mat4 proj; |
102 |
|
|
glm::mat4 viewproj; |
103 |
|
|
}; |
104 |
|
|
|
105 |
|
|
struct GPUSceneData { |
106 |
|
|
glm::vec4 fogColor; // w is for exponent |
107 |
|
|
glm::vec4 fogDistances; // x for min, y for max, zw unused. |
108 |
|
|
glm::vec4 ambientColor; |
109 |
|
|
glm::vec4 sunlightDirection; // w for sun power |
110 |
|
|
glm::vec4 sunlightColor; |
111 |
|
|
}; |
112 |
|
|
|
113 |
|
|
struct GPUObjectData { |
114 |
|
|
glm::mat4 modelMatrix; |
115 |
|
|
}; |
116 |
|
|
|
117 |
|
|
constexpr unsigned int FRAME_OVERLAP = 2; |
118 |
|
|
|
119 |
|
|
class VulkanEngine { |
120 |
|
|
public: |
121 |
|
|
bool _isInitialized{false}; |
122 |
|
|
std::size_t _frameNumber{0}; |
123 |
|
|
int _selectedShader{0}; |
124 |
|
|
|
125 |
|
|
VkExtent2D _windowExtent{1700, 900}; |
126 |
|
|
|
127 |
|
|
struct SDL_Window* _window{nullptr}; |
128 |
|
|
|
129 |
|
|
VulkanEngine(); |
130 |
|
|
static VulkanEngine& instance(); |
131 |
|
|
|
132 |
|
|
VkInstance _instance; |
133 |
|
|
VkDebugUtilsMessengerEXT _debug_messenger; |
134 |
|
|
VkPhysicalDevice _chosenGPU; |
135 |
|
|
VkDevice _device; |
136 |
|
|
|
137 |
|
|
VkPhysicalDeviceProperties _gpuProperties; |
138 |
|
|
|
139 |
|
|
FrameData _frames[FRAME_OVERLAP]; |
140 |
|
|
|
141 |
|
|
VkQueue _graphicsQueue; |
142 |
|
|
uint32_t _graphicsQueueFamily; |
143 |
|
|
|
144 |
|
|
VkRenderPass _renderPass; |
145 |
|
|
|
146 |
|
|
VkSurfaceKHR _surface; |
147 |
|
|
VkSwapchainKHR _swapchain; |
148 |
|
|
VkFormat _swachainImageFormat; |
149 |
|
|
|
150 |
|
|
std::vector<VkFramebuffer> _framebuffers; |
151 |
|
|
std::vector<VkImage> _swapchainImages; |
152 |
|
|
std::vector<VkImageView> _swapchainImageViews; |
153 |
|
|
|
154 |
|
|
DeletionQueue _mainDeletionQueue; |
155 |
|
|
|
156 |
|
|
VmaAllocator _allocator; // vma lib allocator |
157 |
|
|
|
158 |
|
|
// depth resources |
159 |
|
|
VkImageView _depthImageView; |
160 |
|
|
AllocatedImage _depthImage; |
161 |
|
|
|
162 |
|
|
// the format for the depth image |
163 |
|
|
VkFormat _depthFormat; |
164 |
|
|
|
165 |
|
|
VkDescriptorPool _descriptorPool; |
166 |
|
|
|
167 |
|
|
VkSampler _defaultSampler = nullptr; |
168 |
|
|
VkDescriptorSetLayout _globalSetLayout; |
169 |
|
|
VkDescriptorSetLayout _objectSetLayout; |
170 |
|
|
VkDescriptorSetLayout _singleTextureSetLayout; |
171 |
|
|
|
172 |
|
|
GPUSceneData _sceneParameters; |
173 |
|
|
AllocatedBuffer _sceneParameterBuffer; |
174 |
|
|
|
175 |
|
|
UploadContext _uploadContext; |
176 |
|
|
// initializes everything in the engine |
177 |
|
|
void init(); |
178 |
|
|
|
179 |
|
|
// shuts down the engine |
180 |
|
|
void cleanup(); |
181 |
|
|
|
182 |
|
|
// draw loop |
183 |
|
|
void draw(float dt); |
184 |
|
|
|
185 |
|
|
// run main loop |
186 |
|
|
void run(); |
187 |
|
|
|
188 |
|
|
// --- |
189 |
|
|
virtual void start(); |
190 |
|
|
virtual void handle_event(SDL_Event const& event); |
191 |
|
|
virtual void tick(float dt); |
192 |
|
|
virtual void end(); |
193 |
|
|
// --- |
194 |
|
|
|
195 |
|
|
FrameData& get_current_frame(); |
196 |
|
|
FrameData& get_last_frame(); |
197 |
|
|
|
198 |
|
|
// default array of renderable objects |
199 |
|
|
std::vector<RenderObject> _renderables; |
200 |
|
|
|
201 |
|
|
std::unordered_map<std::string, Material> _materials; |
202 |
|
|
std::unordered_map<std::string, Mesh> _meshes; |
203 |
|
|
std::unordered_map<std::string, Texture> _loadedTextures; |
204 |
|
|
// functions |
205 |
|
|
|
206 |
|
|
// create material and add it to the map |
207 |
|
|
Material* |
208 |
|
|
create_material(VkPipeline pipeline, VkPipelineLayout layout, const std::string& name); |
209 |
|
|
|
210 |
|
|
// returns nullptr if it cant be found |
211 |
|
|
Material* get_material(const std::string& name); |
212 |
|
|
|
213 |
|
|
// returns nullptr if it cant be found |
214 |
|
|
Mesh* get_mesh(const std::string& name); |
215 |
|
|
|
216 |
|
|
// our draw function |
217 |
|
|
void draw_objects(VkCommandBuffer cmd, RenderObject* first, int count); |
218 |
|
|
|
219 |
|
|
AllocatedBuffer |
220 |
|
|
create_buffer(size_t allocSize, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage); |
221 |
|
|
|
222 |
|
|
size_t pad_uniform_buffer_size(size_t originalSize); |
223 |
|
|
|
224 |
|
|
void immediate_submit(std::function<void(VkCommandBuffer cmd)>&& function); |
225 |
|
|
|
226 |
|
|
Texture load_texture(const char* file); |
227 |
|
|
|
228 |
|
|
VkSampler get_sampler(); |
229 |
|
|
|
230 |
|
|
private: |
231 |
|
|
void init_vulkan(); |
232 |
|
|
|
233 |
|
|
void init_swapchain(); |
234 |
|
|
|
235 |
|
|
void init_default_renderpass(); |
236 |
|
|
|
237 |
|
|
void init_framebuffers(); |
238 |
|
|
|
239 |
|
|
void init_commands(); |
240 |
|
|
|
241 |
|
|
void init_imgui(); |
242 |
|
|
|
243 |
|
|
void init_sync_structures(); |
244 |
|
|
|
245 |
|
|
void init_pipelines(); |
246 |
|
|
|
247 |
|
|
void init_scene(); |
248 |
|
|
|
249 |
|
|
void init_descriptors(); |
250 |
|
|
|
251 |
|
|
// loads a shader module from a spir-v file. Returns false if it errors |
252 |
|
|
bool load_shader_module(std::string const& filePath, VkShaderModule* outShaderModule); |
253 |
|
|
|
254 |
|
|
void load_meshes(); |
255 |
|
|
|
256 |
|
|
void load_images(); |
257 |
|
|
|
258 |
|
|
void upload_mesh(Mesh& mesh); |
259 |
|
|
|
260 |
|
|
VkSampler new_texture_sampler(); |
261 |
|
|
|
262 |
|
|
public: |
263 |
|
|
ImTextureID load_imtexture(const char* name); |
264 |
|
|
|
265 |
|
|
int get_height(ImTextureID texture); |
266 |
|
|
int get_width(ImTextureID texture); |
267 |
|
|
|
268 |
|
|
private: |
269 |
|
|
std::unordered_map<VkDescriptorSet, Texture> _lookup; |
270 |
|
|
}; |
271 |
|
|
|