even more refactoring

This commit is contained in:
Tyler Murphy 2022-09-19 16:35:45 -04:00
parent 430a008ab3
commit 2f99eee7c5
11 changed files with 154 additions and 201 deletions

View file

@ -1,15 +1,17 @@
#include "xe_engine.hpp"
#include "xe_descriptors.hpp"
#include <string>
namespace xe {
XeEngine::XeEngine(int width, int height, std::string name)
: xeWindow{width, height, name}, xeDevice{xeWindow}, xeRenderer{xeWindow, xeDevice} {
: xeWindow{width, height, name},
xeDevice{xeWindow},
xeRenderer{xeWindow, xeDevice},
xeCamera{} {
loadDescriptors();
};
XeEngine::~XeEngine() {};
void XeEngine::loadDescriptors() {
xeDescriptorPool = XeDescriptorPool::Builder(xeDevice)
.setMaxSets(XeSwapChain::MAX_FRAMES_IN_FLIGHT)
@ -22,12 +24,12 @@ void XeEngine::loadDescriptors() {
.build();
}
std::unique_ptr<XeRenderSystem> XeEngine::createRenderSystem(const std::string &vert, const std::string &frag, typename pushCunstant, typename uniformBuffer) {
std::unique_ptr<XeRenderSystem> XeEngine::createRenderSystem(const std::string &vert, const std::string &frag, uint32_t pushCunstantDataSize, uint32_t uniformBufferDataSize) {
return std::make_unique<XeRenderSystem>(
xeDevice,
xeRenderer,
xeDescriptorPool,
xeDescriptorSetLayout,
*xeDescriptorPool,
*xeDescriptorSetLayout,
vert,
frag,
pushCunstantDataSize,
@ -35,4 +37,32 @@ std::unique_ptr<XeRenderSystem> XeEngine::createRenderSystem(const std::string &
);
}
std::shared_ptr<XeModel> XeEngine::createModel(const std::string &filename) {
return XeModel::createModelFromFile(xeDevice, filename);
}
void XeEngine::render(
XeRenderSystem& xeRenderSystem,
std::vector<XeGameObject>& gameObjects,
void* pushConstantData,
uint32_t pushConstantSize,
void* uniformBufferData,
uint32_t uniformBufferSize) {
auto commandBuffer = xeRenderer.getCurrentCommandBuffer();
xeRenderer.beginSwapChainRenderPass(commandBuffer);
xeRenderSystem.renderGameObjects(
xeRenderer.getFrameIndex(),
commandBuffer,
gameObjects,
pushConstantData,
pushConstantSize,
uniformBufferData,
uniformBufferSize
);
xeRenderer.endSwapChainRenderPass(commandBuffer);
}
}

View file

@ -6,6 +6,7 @@
#include "xe_render_system.hpp"
#include "xe_descriptors.hpp"
#include <string>
namespace xe {
class XeEngine {
@ -26,8 +27,28 @@ class XeEngine {
return xeRenderer;
};
XeCamera& getCamera() {
return xeCamera;
};
std::unique_ptr<XeRenderSystem> createRenderSystem(const std::string &vert, const std::string &frag, uint32_t pushCunstantDataSize, uint32_t uniformBufferDataSize);
std::shared_ptr<XeModel> createModel(const std::string &filename);
bool beginFrame() { return xeRenderer.beginFrame(); }
void endFrame() { return xeRenderer.endFrame(); }
void render(
XeRenderSystem& xeRenderSystem,
std::vector<XeGameObject>& gameObjects,
void* pushConstantData,
uint32_t pushConstantSize,
void* uniformBufferData,
uint32_t uniformBufferSize);
void close() { vkDeviceWaitIdle(xeDevice.device()); }
private:
void loadDescriptors();
@ -35,6 +56,7 @@ class XeEngine {
XeWindow xeWindow;
XeDevice xeDevice;
XeRenderer xeRenderer;
XeCamera xeCamera;
std::unique_ptr<XeDescriptorPool> xeDescriptorPool;
std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout;

View file

@ -145,7 +145,7 @@ namespace xe {
configInfo.rasterizationInfo.rasterizerDiscardEnable = VK_FALSE;
configInfo.rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
configInfo.rasterizationInfo.lineWidth = 1.0f;
configInfo.rasterizationInfo.cullMode = VK_CULL_MODE_NONE;
configInfo.rasterizationInfo.cullMode = VK_CULL_MODE_BACK_BIT;
configInfo.rasterizationInfo.frontFace = VK_FRONT_FACE_CLOCKWISE;
configInfo.rasterizationInfo.depthBiasEnable = VK_FALSE;
configInfo.rasterizationInfo.depthBiasConstantFactor = 0.0f;

View file

@ -12,14 +12,15 @@
#include <memory>
#include <stdexcept>
#include <iostream>
namespace xe {
template <typename P, typename U>
XeRenderSystem::XeRenderSystem(
XeDevice &device,
XeRenderer &renderer,
std::unique_ptr<XeDescriptorPool> &xeDescriptorPool,
std::unique_ptr<XeDescriptorSetLayout> &xeDescriptorSetLayout,
XeDescriptorPool &xeDescriptorPool,
XeDescriptorSetLayout &xeDescriptorSetLayout,
std::string vert,
std::string frag,
uint32_t pushCunstantDataSize,
@ -31,12 +32,9 @@ XeRenderSystem::XeRenderSystem(
}
template <typename P, typename U>
XeRenderSystem::~XeRenderSystem() {};
template <typename P, typename U>
void XeRenderSystem::createUniformBuffers(std::unique_ptr<XeDescriptorPool> &xeDescriptorPool, std::unique_ptr<XeDescriptorSetLayout> &xeDescriptorSetLayout, uint32_t uniformBufferDataSize) {
void XeRenderSystem::createUniformBuffers(XeDescriptorPool &xeDescriptorPool, XeDescriptorSetLayout &xeDescriptorSetLayout, uint32_t uniformBufferDataSize) {
if(uniformBufferDataSize == 0) return;
uboBuffers = std::vector<std::unique_ptr<XeBuffer>>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
@ -53,24 +51,24 @@ void XeRenderSystem::createUniformBuffers(std::unique_ptr<XeDescriptorPool> &xeD
descriptorSets = std::vector<VkDescriptorSet>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
for (int i = 0; i < descriptorSets.size(); i++) {
auto bufferInfo = uboBuffers[i]->descriptorInfo();
XeDescriptorWriter(*xeDescriptorSetLayout, *xeDescriptorPool)
XeDescriptorWriter(xeDescriptorSetLayout, xeDescriptorPool)
.writeBuffer(0, &bufferInfo)
.build(descriptorSets[i]);
}
}
template <typename P, typename U>
void XeRenderSystem::createPipelineLayout(std::unique_ptr<XeDescriptorSetLayout> &xeDescriptorSetLayout, uint32_t pushCunstantDataSize, uint32_t uniformBufferDataSize) {
void XeRenderSystem::createPipelineLayout(XeDescriptorSetLayout &xeDescriptorSetLayout, uint32_t pushCunstantDataSize, uint32_t uniformBufferDataSize) {
VkPushConstantRange pushConstantRange;
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
pushConstantRange.offset = 0;
pushConstantRange.size = pushCunstantDataSize;
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
if (pushCunstantDataSize > 0) {
VkPushConstantRange pushConstantRange;
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
pushConstantRange.offset = 0;
pushConstantRange.size = pushCunstantDataSize;
pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
} else {
@ -79,7 +77,7 @@ void XeRenderSystem::createPipelineLayout(std::unique_ptr<XeDescriptorSetLayout>
}
if (uniformBufferDataSize > 0) {
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{xeDescriptorSetLayout->getDescriptorSetLayout()};
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{xeDescriptorSetLayout.getDescriptorSetLayout()};
pipelineLayoutInfo.setLayoutCount = static_cast<uint32_t>(descriptorSetLayouts.size());
pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
} else {
@ -90,10 +88,10 @@ void XeRenderSystem::createPipelineLayout(std::unique_ptr<XeDescriptorSetLayout>
if(vkCreatePipelineLayout(xeDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
std::runtime_error("failed to create pipeline layout!");
}
}
template <typename P, typename U>
void XeRenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag) {
assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout");
@ -109,35 +107,46 @@ void XeRenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, s
);
}
void XeRenderSystem::renderGameObjects(
int frameIndex,
VkCommandBuffer commandBuffer,
std::vector<XeGameObject> &gameObjects,
void *pushConstantData,
uint32_t pushConstantSize,
void* uniformBufferData,
uint32_t uniformBufferSize) {
template <typename P, typename U>
void XeRenderSystem::renderGameObjects(XeFrameInfo &frameInfo, std::vector<XeGameObject> &gameObjects, XeRenderSystem::XeData pushConstantData) {
xePipeline->bind(frameInfo.commandBuffer);
uboBuffers[frameIndex]->writeToBuffer(uniformBufferData);
uboBuffers[frameIndex]->flush();
if(uboBuffers.size() > 0) {
xePipeline->bind(commandBuffer);
if(pushConstantData == NULL) {
vkCmdBindDescriptorSets(
frameInfo.commandBuffer,
commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelineLayout,
0,
1,
&descriptorSets[frameInfo.frameIndex],
&descriptorSets[frameIndex],
0,
nullptr);
}
for (auto& obj: gameObjects) {
if(pushConstantData == NULL) {
vkCmdPushConstants(
frameInfo.commandBuffer,
commandBuffer,
pipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
0,
sizeof(pushConstantData),
pushConstantSize,
&pushConstantData);
}
obj.model->bind(frameInfo.commandBuffer);
obj.model->draw(frameInfo.commandBuffer);
obj.model->bind(commandBuffer);
obj.model->draw(commandBuffer);
}
}

View file

@ -5,12 +5,13 @@
#include "xe_pipeline.hpp"
#include "xe_frame_info.hpp"
#include "xe_game_object.hpp"
#include "xe_descriptors.hpp"
#include "xe_renderer.hpp"
#include <memory>
namespace xe {
template<typename P, typename U>
class XeRenderSystem {
public:
@ -19,23 +20,33 @@ class XeRenderSystem {
XeRenderSystem(
XeDevice &device,
XeRenderer &renderer,
std::unique_ptr<XeDescriptorPool> &xeDescriptorPool,
std::unique_ptr<XeDescriptorSetLayout> &xeDescriptorSetLayout,
XeDescriptorPool &xeDescriptorPool,
XeDescriptorSetLayout &xeDescriptorSetLayout,
std::string vert,
std::string frag,
uint32_t pushCunstantDataSize,
uint32_t uniformBufferDataSize);
uint32_t uniformBufferDataSize
);
~XeRenderSystem();
XeRenderSystem(const XeRenderSystem &) = delete;
XeRenderSystem operator=(const XeRenderSystem &) = delete;
void renderGameObjects(XeFrameInfo &frameInfo, std::vector<XeGameObject> &gameObjects, XeRenderSystem::XeData pushConstantData);
void setUnifroms(XeFrameInfo & frameInfo);
void renderGameObjects(
int frameIndex,
VkCommandBuffer commandBuffer,
std::vector<XeGameObject> &gameObjects,
void *pushConstantData,
uint32_t pushConstantSize,
void* uniformBufferData,
uint32_t uniformBufferSize);
private:
void createUniformBuffers(std::unique_ptr<XeDescriptorPool> &xeDescriptorPool, std::unique_ptr<XeDescriptorSetLayout> &xeDescriptorSetLayout, uint32_t uniformBufferDataSize);
void createPipelineLayout(std::unique_ptr<XeDescriptorSetLayout> &xeDescriptorSetLayout, uint32_t pushCunstantDataSize, uint32_t uniformBufferDataSize);
void createUniformBuffers(XeDescriptorPool &xeDescriptorPool, XeDescriptorSetLayout &xeDescriptorSetLayout, uint32_t uniformBufferDataSize);
void createPipelineLayout(XeDescriptorSetLayout &xeDescriptorSetLayout, uint32_t pushCunstantDataSize, uint32_t uniformBufferDataSize);
void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag);
XeDevice& xeDevice;

View file

@ -17,7 +17,6 @@ namespace xe {
XeRenderer::XeRenderer(XeWindow& window, XeDevice& device) : xeWindow{window}, xeDevice{device} {
recreateSwapChain();
createCommandBuffers();
loadDescriptorPool();
}
XeRenderer::~XeRenderer() { freeCommandBuffers(); }

Binary file not shown.

Binary file not shown.

View file

@ -3,7 +3,6 @@
#include "xe_camera.hpp"
#include "xe_game_object.hpp"
#include "xe_model.hpp"
#include "simple_render_system.hpp"
#include "keyboard_movement_controller.hpp"
@ -16,12 +15,17 @@
#include <chrono>
#include <cassert>
#include <stdexcept>
#include <iostream>
namespace xe {
struct GlobalUbo {
glm::mat4 projectionView{1.f};
glm::vec3 lightDirection = glm::normalize(glm::vec3{-1.f, 3.f, 1.f});
struct UniformBuffer {
alignas(16) glm::mat4 projectionView{1.f};
alignas(4) glm::vec3 lightDirection = glm::normalize(glm::vec3{-1.f, 3.f, 1.f});
};
struct PushConstant {
alignas(16) glm::mat4 modelMatrix{1.f};
alignas(16) glm::mat4 normalMatrix{1.f};
};
FirstApp::FirstApp() : xeEngine{WIDTH, HEIGHT, "Hello, Vulkan!"} {
@ -32,7 +36,12 @@ FirstApp::~FirstApp() {}
void FirstApp::run() {
std::unique_ptr<XeRenderSystem> renderSystem = xeEngine.createRenderSystem("fw","fd",0,0);
std::unique_ptr<XeRenderSystem> simpleRenderSystem = xeEngine.createRenderSystem(
"res/shaders/simple_shader.vert.spv",
"res/shaders/simple_shader.frag.spv",
sizeof(PushConstant),
sizeof(UniformBuffer));
XeCamera camera{};
camera.setViewTarget(glm::vec3(-1.f, -2.f, 20.f), glm::vec3(0.f, 0.f, 2.5f));
@ -51,34 +60,38 @@ void FirstApp::run() {
cameraController.moveInPlaneXZ(xeEngine.getWindow().getGLFWwindow(), frameTime, viewerObject);
camera.setViewYXZ(viewerObject.transform.translation, viewerObject.transform.rotation);
float aspect = xeRenderer.getAspectRatio();
float aspect = xeEngine.getRenderer().getAspectRatio();
camera.setPerspectiveProjection(glm::radians(50.f), aspect, 0.1f, 100.f);
if(auto commandBuffer = xeRenderer.beginFrame()) {
if(xeEngine.beginFrame()) {
int frameIndex = xeRenderer.getFrameIndex();
PushConstant pc{};
pc.modelMatrix = gameObjects[0].transform.mat4();
pc.normalMatrix = gameObjects[0].transform.normalMatrix();
// update
GlobalUbo ubo{};
UniformBuffer ubo{};
ubo.projectionView = camera.getProjection() * camera.getView();
// uboBuffers[frameIndex]->writeToBuffer(&ubo);
// uboBuffers[frameIndex]->flush();
// // render
// xeRenderer.beginSwapChainRenderPass(commandBuffer);
// simpleRenderSystem.renderGameObjects(frameInfo, gameObjects);
// xeRenderer.endSwapChainRenderPass(commandBuffer);
// xeRenderer.endFrame();
}
xeEngine.render(
*simpleRenderSystem,
gameObjects,
&pc,
sizeof(pc),
&ubo,
sizeof(ubo)
);
xeEngine.endFrame();
}
}
vkDeviceWaitIdle(xeDevice.device());
xeEngine.close();
}
void FirstApp::loadGameObjects() {
std::shared_ptr<XeModel> xeModel = XeModel::createModelFromFile(xeDevice, "res/models/stanford-dragon.obj");
std::shared_ptr<XeModel> xeModel = xeEngine.createModel("res/models/stanford-dragon.obj");
auto cube = XeGameObject::createGameObject();
cube.model = xeModel;

View file

@ -1,94 +0,0 @@
#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);
}
}
}

View file

@ -1,37 +0,0 @@
#pragma once
#include "xe_camera.hpp"
#include "xe_pipeline.hpp"
#include "xe_device.hpp"
#include "xe_game_object.hpp"
#include "xe_frame_info.hpp"
#include <memory>
#include <vector>
#include <vulkan/vulkan_core.h>
namespace xe {
class SimpleRenderSystem {
public:
SimpleRenderSystem(XeDevice& device, VkRenderPass renderPass, VkDescriptorSetLayout globalSetLayout);
~SimpleRenderSystem();
SimpleRenderSystem(const SimpleRenderSystem &) = delete;
SimpleRenderSystem operator=(const SimpleRenderSystem &) = delete;
void renderGameObjects(
XeFrameInfo &frameInfo,
std::vector<XeGameObject> &gameObjects
);
private:
void createPipelineLayout(VkDescriptorSetLayout globalSetLayout);
void createPipeline(VkRenderPass renderPass);
XeDevice& xeDevice;
std::unique_ptr<XePipeline> xePipeline;
VkPipelineLayout pipelineLayout;
};
}