diff options
Diffstat (limited to 'src/simple_render_system.cpp')
-rw-r--r-- | src/simple_render_system.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/simple_render_system.cpp b/src/simple_render_system.cpp new file mode 100644 index 0000000..6e4ab30 --- /dev/null +++ b/src/simple_render_system.cpp @@ -0,0 +1,94 @@ +#include "simple_render_system.hpp" +#include "xe_device.hpp" +#include <vector> +#include <vulkan/vulkan_core.h> + +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include <glm/glm.hpp> +#include <glm/gtc/constants.hpp> + +#include <array> +#include <cassert> +#include <stdexcept> + +namespace xe { + +struct SimplePushConstantData { + glm::mat4 modelMatrix{1.f}; + glm::mat4 normalMatrix{1.f}; +}; + +SimpleRenderSystem::SimpleRenderSystem(XeDevice& device, VkRenderPass renderPass, VkDescriptorSetLayout globalSetLayout) : xeDevice{device} { + createPipelineLayout(globalSetLayout); + createPipeline(renderPass); +} + +SimpleRenderSystem::~SimpleRenderSystem() { vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr); } + +void SimpleRenderSystem::createPipelineLayout(VkDescriptorSetLayout globalSetLayout) { + + VkPushConstantRange pushConstantRange; + pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + pushConstantRange.offset = 0; + pushConstantRange.size = sizeof(SimplePushConstantData); + + std::vector<VkDescriptorSetLayout> descriptorSetLayouts{globalSetLayout}; + + VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.setLayoutCount = static_cast<uint32_t>(descriptorSetLayouts.size()); + pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data(); + pipelineLayoutInfo.pushConstantRangeCount = 1; + pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange; + if(vkCreatePipelineLayout(xeDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) { + std::runtime_error("failed to create pipeline layout!"); + } +} + +void SimpleRenderSystem::createPipeline(VkRenderPass renderPass) { + assert(pipelineLayout != nullptr && "Canor create pipeline before pipeline layout"); + + PipelineConfigInfo pipelineConfig{}; + XePipeline::defaultPipelineConfigInfo(pipelineConfig); + pipelineConfig.renderPass = renderPass; + pipelineConfig.pipelineLayout = pipelineLayout; + xePipeline = std::make_unique<XePipeline>( + xeDevice, + "res/shaders/simple_shader.vert.spv", + "res/shaders/simple_shader.frag.spv", + pipelineConfig + ); +} + +void SimpleRenderSystem::renderGameObjects(XeFrameInfo &frameInfo, std::vector<XeGameObject> &gameObjects) { + xePipeline->bind(frameInfo.commandBuffer); + + vkCmdBindDescriptorSets( + frameInfo.commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipelineLayout, + 0, + 1, + &frameInfo.globalDescriptorSet, + 0, + nullptr); + + for (auto& obj: gameObjects) { + SimplePushConstantData push{}; + push.modelMatrix = obj.transform.mat4(); + push.normalMatrix = obj.transform.normalMatrix(); + + vkCmdPushConstants( + frameInfo.commandBuffer, + pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + 0, + sizeof(SimplePushConstantData), + &push); + obj.model->bind(frameInfo.commandBuffer); + obj.model->draw(frameInfo.commandBuffer); + } +} + +}
\ No newline at end of file |