summaryrefslogtreecommitdiff
path: root/src/simple_render_system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/simple_render_system.cpp')
-rw-r--r--src/simple_render_system.cpp94
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