#include "simple_render_system.hpp" #include "xe_device.hpp" #include #include #define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include #include #include #include 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 descriptorSetLayouts{globalSetLayout}; VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.setLayoutCount = static_cast(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( xeDevice, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv", pipelineConfig ); } void SimpleRenderSystem::renderGameObjects(XeFrameInfo &frameInfo, std::vector &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); } } }