#include "simple_render_system.hpp" #include #include #define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include namespace cve { struct SimplePushConstantData{ glm::mat2 transform{1.f}; // Identity matrix glm::vec2 offset; alignas(16) glm::vec3 color; }; SimpleRenderSystem::SimpleRenderSystem(CveDevice& device, VkRenderPass renderPass): cveDevice{device} { createPipelineLayout(); createPipeline(renderPass); } SimpleRenderSystem::~SimpleRenderSystem() { vkDestroyPipelineLayout(cveDevice.device(), pipelineLayout, nullptr); } void SimpleRenderSystem::createPipelineLayout() { VkPushConstantRange pushConstantRange{}; pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; pushConstantRange.offset = 0; pushConstantRange.size = sizeof(SimplePushConstantData); VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.setLayoutCount = 0; pipelineLayoutInfo.pSetLayouts = nullptr; pipelineLayoutInfo.pushConstantRangeCount = 1; pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange; if (vkCreatePipelineLayout(cveDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) { throw std::runtime_error("Failed to create pipeline layout"); } } void SimpleRenderSystem::createPipeline(VkRenderPass renderPass) { assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout"); PipelineConfigInfo pipelineConfig{}; CvePipeline::defaultPipelineConfigInfo(pipelineConfig); pipelineConfig.renderPass = renderPass; pipelineConfig.pipelineLayout = pipelineLayout; cvePipeline = std::make_unique( cveDevice, "shaders/simple_shader.vert.spv", "shaders/simple_shader.frag.spv", pipelineConfig ); } void SimpleRenderSystem::renderGameObjects(VkCommandBuffer commandBuffer, std::vector &gameObjects) { cvePipeline->bind(commandBuffer); for (auto& obj: gameObjects) { obj.transform2d.rotation = glm::mod(obj.transform2d.rotation + 0.001f, glm::two_pi()); SimplePushConstantData push{}; push.offset = obj.transform2d.translation; push.color = obj.color; push.transform = obj.transform2d.mat2(); vkCmdPushConstants( commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(SimplePushConstantData), &push ); obj.model->bind(commandBuffer); obj.model->draw(commandBuffer); } } }