Vulkan Engine 0.0
A simple Vulkan engine demo
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
engine_render_system.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "defines.hpp"
4#include "engine_pipeline.hpp"
5#include "engine_device.hpp"
7#include "engine_camera.hpp"
9
10#define GLM_FORCE_RADIANS
11#define GLM_FORCE_DEPTH_ZERO_TO_ONE
12#include <glm/glm.hpp>
13#include <glm/gtc/constants.hpp>
14#include <array>
15#include <memory>
16#include <stdexcept>
17#include <utility>
18#include <vector>
19#include <vulkan/vulkan_core.h>
20
22 glm::mat4 transform{1.f};
23 glm::vec4 color;
24 glm::vec4 camera_pos;
25 glm::vec4 has_normalmap{0.0f};
26};
27
32private:
33 EngineDevice &device;
35 std::unique_ptr<EnginePipeline> pipeline;
36 VkPipelineLayout pipeline_layout;
37
38 void create_pipeline_layout() {
39 VkPushConstantRange push_constant_range{};
40 push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
41 push_constant_range.offset = 0;
42 push_constant_range.size = sizeof(SimplePushConstantData);
43
44 VkPipelineLayoutCreateInfo pipeline_layout_info{};
45 pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
46
47 std::vector<VkDescriptorSetLayout> descriptor_sets_layouts{};
48 descman.get_regular_layouts(descriptor_sets_layouts);
49 pipeline_layout_info.setLayoutCount = descriptor_sets_layouts.size();
50 pipeline_layout_info.pSetLayouts = descriptor_sets_layouts.data();
51
52 pipeline_layout_info.pushConstantRangeCount = 1;
53 pipeline_layout_info.pPushConstantRanges = &push_constant_range;
54
55 if (vkCreatePipelineLayout(
56 device.device(), &pipeline_layout_info, nullptr, &pipeline_layout
57 ) != VK_SUCCESS) {
58 throw std::runtime_error("failed to create pipeline layout");
59 }
60 }
61
63 void create_pipeline(VkRenderPass render_pass) {
64 assert(pipeline_layout != nullptr && "Cannot create pipeline before pipeline layout");
65
66 PipelineConfigInfo pipeline_config{};
68 pipeline_config.render_pass = render_pass;
69 pipeline_config.pipeline_layout = pipeline_layout;
70 std::vector<PipelineShaderData> shaders_data = {
71 {
72 SHADERS_DIR+"/diffuse.vert.spv",
73 VK_SHADER_STAGE_VERTEX_BIT
74 },
75 {
76 SHADERS_DIR+"/diffuse.geom.spv",
77 VK_SHADER_STAGE_GEOMETRY_BIT
78 },
79 {
80 SHADERS_DIR+"/diffuse.frag.spv",
81 VK_SHADER_STAGE_FRAGMENT_BIT
82 }
83 };
84 pipeline = std::make_unique<EnginePipeline>(
85 device,
86 shaders_data,
87 pipeline_config
88 );
89 }
91
92public:
94 EngineDevice &device, EngineDescriptorManager &descman, VkRenderPass render_pass
95 ) : device{device}, descman{descman} {
96 create_pipeline_layout();
97 create_pipeline(render_pass);
98 }
99
101 vkDestroyPipelineLayout(device.device(), pipeline_layout, nullptr);
102 }
103
104 // RAII
107
109 VkCommandBuffer command_buffer,
110 std::vector<EngineObjectQuat> &objects,
111 uint32_t frame_index
112 ) {
114 render_engine_objects(command_buffer, objects, push, frame_index);
115 }
116
118 VkCommandBuffer command_buffer,
119 std::vector<EngineObjectQuat> &objects,
121 uint32_t frame_index
122 ) {
123 pipeline->bind(command_buffer);
124 // TODO: bind descriptorsets only if pipeline changed?
125 // amend: different pipelines are now used per render pass, therefore
126 // this should always happen?
127 descman.bind_descriptor_set(command_buffer, pipeline_layout, frame_index);
128
129 for (auto &obj: objects) {
130 descman.bind_texture(command_buffer, pipeline_layout, obj);
131
132 push.color = glm::vec4(obj.color, 1.0f);
133 push.transform = obj.transform.mat4();
134 push.has_normalmap = glm::vec4(obj.model->has_normalmap(), 0.0f, 0.0f, 0.0f);
135
136 vkCmdPushConstants(
137 command_buffer, pipeline_layout,
138 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
139 0, sizeof(SimplePushConstantData), &push
140 );
141 obj.model->bind(command_buffer);
142 obj.model->draw(command_buffer);
143 }
144 }
145};
Mega-class responsible for handling everything to do with descriptors.
Definition: engine_descriptors.hpp:23
void bind_texture(VkCommandBuffer command_buffer, VkPipelineLayout pipeline_layout, EngineObjectQuat &object)
Definition: engine_descriptors.hpp:490
void bind_descriptor_set(VkCommandBuffer command_buffer, VkPipelineLayout pipeline_layout, uint32_t frame_index)
Definition: engine_descriptors.hpp:413
void get_regular_layouts(std::vector< VkDescriptorSetLayout > &layouts)
Definition: engine_descriptors.hpp:385
Abstraction around VkDevice, managing everything to do with the physical and logical device,...
Definition: engine_device.hpp:109
VkDevice device()
Definition: engine_device.hpp:482
static void default_pipeline_config_info(PipelineConfigInfo &config_info)
Definition: engine_pipeline.hpp:207
Standard render system used for rendering EngineObjectQuat objects.
Definition: engine_render_system.hpp:31
EngineRenderSystem(EngineDevice &device, EngineDescriptorManager &descman, VkRenderPass render_pass)
[Creating a regular Pipeline]
Definition: engine_render_system.hpp:93
EngineRenderSystem(const EngineRenderSystem &)=delete
void render_engine_objects(VkCommandBuffer command_buffer, std::vector< EngineObjectQuat > &objects, SimplePushConstantData &push, uint32_t frame_index)
Definition: engine_render_system.hpp:117
EngineRenderSystem & operator=(const EngineRenderSystem &)=delete
void render_engine_objects(VkCommandBuffer command_buffer, std::vector< EngineObjectQuat > &objects, uint32_t frame_index)
Definition: engine_render_system.hpp:108
~EngineRenderSystem()
Definition: engine_render_system.hpp:100
Definition: engine_pipeline.hpp:13
Definition: engine_render_system.hpp:21
glm::vec4 color
Definition: engine_render_system.hpp:23
glm::vec4 camera_pos
Definition: engine_render_system.hpp:24
glm::mat4 transform
Definition: engine_render_system.hpp:22
glm::vec4 has_normalmap
Definition: engine_render_system.hpp:25