summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.env.example1
-rw-r--r--Makefile4
-rw-r--r--engine/xe_engine.cpp68
-rw-r--r--engine/xe_engine.hpp44
-rw-r--r--engine/xe_frame_info.hpp16
-rw-r--r--engine/xe_render_system.cpp82
-rw-r--r--engine/xe_render_system.hpp32
-rwxr-xr-xres/shaders/simple_shader.vert2
-rw-r--r--res/shaders/simple_shader.vert.spvbin2520 -> 2816 bytes
-rwxr-xr-xsrc/first_app.cpp85
-rwxr-xr-xsrc/first_app.hpp12
-rw-r--r--src/keyboard_movement_controller.cpp4
-rw-r--r--src/keyboard_movement_controller.hpp4
-rwxr-xr-xsrc/main.cpp2
-rw-r--r--src/simple_renderer.cpp26
-rw-r--r--src/simple_renderer.hpp36
16 files changed, 195 insertions, 223 deletions
diff --git a/.env.example b/.env.example
deleted file mode 100644
index d316828..0000000
--- a/.env.example
+++ /dev/null
@@ -1 +0,0 @@
-VULKAN_SDK=/home/tylerm/Documents/Vulkan \ No newline at end of file
diff --git a/Makefile b/Makefile
index 96e7b3a..561c5bf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,9 @@
-include .env
-
CC = clang++
INCFLAGS = -Isrc
INCFLAGS += -Iengine
INCFLAGS += -Ilib/glfw/include
INCFLAGS += -Ilib/glm
-INCFLAGS += -L${VULKAN_SDK}/lib -lvulkan
CCFLAGS = -std=c++17 -O2 -g
CCFLAGS += $(INCFLAGS)
@@ -15,6 +12,7 @@ LDFLAGS = -lm
LDFLAGS += $(INCFLAGS)
LDFLAGS += lib/glfw/src/libglfw3.a
LDFLAGS += lib/glm/glm/libglm_static.a
+LDFLAGS += -lvulkan
SRC = $(shell find src -name "*.cpp")
SRC += $(shell find engine -name "*.cpp")
diff --git a/engine/xe_engine.cpp b/engine/xe_engine.cpp
index 6de221a..ea54bb4 100644
--- a/engine/xe_engine.cpp
+++ b/engine/xe_engine.cpp
@@ -1,16 +1,14 @@
#include "xe_engine.hpp"
-#include "xe_descriptors.hpp"
+#include <chrono>
-#include <string>
namespace xe {
-XeEngine::XeEngine(int width, int height, std::string name)
- : xeWindow{width, height, name},
- xeDevice{xeWindow},
- xeRenderer{xeWindow, xeDevice},
- xeCamera{} {
- loadDescriptors();
- };
+XeEngine::XeEngine(int width, int height, std::string name) : xeWindow{width, height, name},
+ xeDevice{xeWindow},
+ xeRenderer{xeWindow, xeDevice},
+ xeCamera{} {
+ loadDescriptors();
+};
void XeEngine::loadDescriptors() {
xeDescriptorPool = XeDescriptorPool::Builder(xeDevice)
@@ -24,45 +22,27 @@ void XeEngine::loadDescriptors() {
.build();
}
-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,
- vert,
- frag,
- pushCunstantDataSize,
- uniformBufferDataSize
- );
-}
-
-std::shared_ptr<XeModel> XeEngine::createModel(const std::string &filename) {
+std::shared_ptr<XeModel> XeEngine::loadModelFromFile(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);
+std::shared_ptr<XeModel> XeEngine::loadModelFromData(std::vector<XeModel::Vertex> vertices, std::vector<uint32_t> indices) {
+ XeModel::Builder builder{};
+ builder.vertices = vertices;
+ if(&indices == NULL) {
+ builder.indices = indices;
+ }
+ return std::make_shared<XeModel>(xeDevice, builder);
+}
- xeRenderSystem.renderGameObjects(
- xeRenderer.getFrameIndex(),
- commandBuffer,
- gameObjects,
- pushConstantData,
- pushConstantSize,
- uniformBufferData,
- uniformBufferSize
- );
-
- xeRenderer.endSwapChainRenderPass(commandBuffer);
+bool XeEngine::poll() {
+ glfwPollEvents();
+ auto newTime = std::chrono::high_resolution_clock::now();
+ frameTime = std::chrono::duration<float, std::chrono::seconds::period>(newTime - currentTime).count();
+ currentTime = newTime;
+ float aspect = xeRenderer.getAspectRatio();
+ xeCamera.setPerspectiveProjection(glm::radians(FOV), aspect, 0.1f, 100.f);
+ return !xeWindow.shouldClose();
}
} \ No newline at end of file
diff --git a/engine/xe_engine.hpp b/engine/xe_engine.hpp
index d9f79ca..d3862d4 100644
--- a/engine/xe_engine.hpp
+++ b/engine/xe_engine.hpp
@@ -3,8 +3,9 @@
#include "xe_window.hpp"
#include "xe_device.hpp"
#include "xe_renderer.hpp"
-#include "xe_render_system.hpp"
+#include "xe_camera.hpp"
#include "xe_descriptors.hpp"
+#include <chrono>
#include <string>
namespace xe {
@@ -14,41 +15,25 @@ class XeEngine {
public:
XeEngine(int width, int height, std::string name);
+
~XeEngine() {};
XeEngine(const XeEngine&) = delete;
XeEngine operator=(const XeEngine&) = delete;
- XeWindow& getWindow() {
- return xeWindow;
- };
-
- XeRenderer& getRenderer() {
- return xeRenderer;
- };
-
- XeCamera& getCamera() {
- return xeCamera;
- };
+ XeWindow& getWindow() {return xeWindow;}
+ 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);
+ std::shared_ptr<XeModel> loadModelFromFile(const std::string &filename);
+ std::shared_ptr<XeModel> loadModelFromData(std::vector<XeModel::Vertex> vertices, std::vector<uint32_t> indices);
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 endFrame() { xeRenderer.endFrame(); }
void close() { vkDeviceWaitIdle(xeDevice.device()); }
+ bool poll();
+ float getFrameTime() { return frameTime; }
+
private:
void loadDescriptors();
@@ -58,8 +43,15 @@ class XeEngine {
XeRenderer xeRenderer;
XeCamera xeCamera;
+ std::chrono::_V2::system_clock::time_point currentTime;
+ float frameTime;
+
+ float FOV = 50.f;
+
std::unique_ptr<XeDescriptorPool> xeDescriptorPool;
std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout;
+
+ friend class XeRenderSystem;
};
} \ No newline at end of file
diff --git a/engine/xe_frame_info.hpp b/engine/xe_frame_info.hpp
deleted file mode 100644
index 074895d..0000000
--- a/engine/xe_frame_info.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "xe_camera.hpp"
-
-#include <vulkan/vulkan.h>
-
-namespace xe {
-
-struct XeFrameInfo {
- int frameIndex;
- float frameTime;
- VkCommandBuffer commandBuffer;
- XeCamera &camera;
-};
-
-} \ No newline at end of file
diff --git a/engine/xe_render_system.cpp b/engine/xe_render_system.cpp
index 8a28473..6726632 100644
--- a/engine/xe_render_system.cpp
+++ b/engine/xe_render_system.cpp
@@ -3,11 +3,11 @@
#include <vulkan/vulkan.h>
#include "xe_device.hpp"
#include "xe_pipeline.hpp"
-#include "xe_frame_info.hpp"
#include "xe_game_object.hpp"
#include "xe_swap_chain.hpp"
#include "xe_renderer.hpp"
#include "xe_descriptors.hpp"
+#include "xe_engine.hpp"
#include <memory>
#include <stdexcept>
@@ -17,18 +17,15 @@
namespace xe {
XeRenderSystem::XeRenderSystem(
- XeDevice &device,
- XeRenderer &renderer,
- XeDescriptorPool &xeDescriptorPool,
- XeDescriptorSetLayout &xeDescriptorSetLayout,
+ XeEngine &xeEngine,
std::string vert,
std::string frag,
uint32_t pushCunstantDataSize,
uint32_t uniformBufferDataSize)
- : xeDevice{device} {
- createUniformBuffers(xeDescriptorPool, xeDescriptorSetLayout, uniformBufferDataSize);
- createPipelineLayout(xeDescriptorSetLayout, pushCunstantDataSize, uniformBufferDataSize);
- createPipeline(renderer.getSwapChainRenderPass(), vert, frag);
+ : xeDevice{xeEngine.xeDevice}, xeRenderer{xeEngine.xeRenderer} {
+ createUniformBuffers(*xeEngine.xeDescriptorPool, *xeEngine.xeDescriptorSetLayout, uniformBufferDataSize);
+ createPipelineLayout(*xeEngine.xeDescriptorSetLayout, pushCunstantDataSize, uniformBufferDataSize);
+ createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag);
}
@@ -108,55 +105,54 @@ 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) {
-
- uboBuffers[frameIndex]->writeToBuffer(uniformBufferData);
- uboBuffers[frameIndex]->flush();
-
- xePipeline->bind(commandBuffer);
-
- if(pushConstantSize > 0) {
+void XeRenderSystem::loadPushConstant(void *pushConstantData, uint32_t pushConstantSize) {
+ if(!boundPipeline) {
+ xeRenderer.beginSwapChainRenderPass(xeRenderer.getCurrentCommandBuffer());
+ xePipeline->bind(xeRenderer.getCurrentCommandBuffer());
+ boundPipeline = true;
+ }
+ if(!boundDescriptor) {
vkCmdBindDescriptorSets(
- commandBuffer,
+ xeRenderer.getCurrentCommandBuffer(),
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelineLayout,
0,
1,
- &descriptorSets[frameIndex],
+ &descriptorSets[xeRenderer.getFrameIndex()],
0,
nullptr);
+ boundDescriptor = true;
}
-
- for (auto& obj: gameObjects) {
-
- struct PushConstant {
- glm::mat4 modelMatrix;
- glm::mat4 normalMatrix;
- };
-
- PushConstant pc = PushConstant{obj.transform.mat4(), obj.transform.normalMatrix()};
-
- if(pushConstantSize > 0) {
- vkCmdPushConstants(
- commandBuffer,
+ vkCmdPushConstants(
+ xeRenderer.getCurrentCommandBuffer(),
pipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
0,
pushConstantSize,
- &pc);
- }
+ pushConstantData);
+}
+
+void XeRenderSystem::loadUniformObject(void *uniformBufferData, uint32_t uniformBufferSize) {
+ uboBuffers[xeRenderer.getFrameIndex()]->writeToBuffer(uniformBufferData);
+ uboBuffers[xeRenderer.getFrameIndex()]->flush();
+}
- obj.model->bind(commandBuffer);
- obj.model->draw(commandBuffer);
+void XeRenderSystem::render(XeGameObject &gameObject) {
+ if(!boundPipeline){
+ xeRenderer.beginSwapChainRenderPass(xeRenderer.getCurrentCommandBuffer());
+ xePipeline->bind(xeRenderer.getCurrentCommandBuffer());
+ boundPipeline = true;
}
+ gameObject.model->bind(xeRenderer.getCurrentCommandBuffer());
+ gameObject.model->draw(xeRenderer.getCurrentCommandBuffer());
+
+}
+
+void XeRenderSystem::stop() {
+ boundPipeline = false;
+ boundDescriptor = false;
+ xeRenderer.endSwapChainRenderPass(xeRenderer.getCurrentCommandBuffer());
}
} \ No newline at end of file
diff --git a/engine/xe_render_system.hpp b/engine/xe_render_system.hpp
index 608e03a..fa56fdd 100644
--- a/engine/xe_render_system.hpp
+++ b/engine/xe_render_system.hpp
@@ -3,10 +3,10 @@
#include <vulkan/vulkan.h>
#include "xe_device.hpp"
#include "xe_pipeline.hpp"
-#include "xe_frame_info.hpp"
#include "xe_game_object.hpp"
#include "xe_descriptors.hpp"
#include "xe_renderer.hpp"
+#include "xe_engine.hpp"
#include <memory>
@@ -14,42 +14,36 @@ namespace xe {
class XeRenderSystem {
public:
-
- struct XeData{};
-
+
XeRenderSystem(
- XeDevice &device,
- XeRenderer &renderer,
- XeDescriptorPool &xeDescriptorPool,
- XeDescriptorSetLayout &xeDescriptorSetLayout,
+ XeEngine &xeEngine,
std::string vert,
std::string frag,
uint32_t pushCunstantDataSize,
uint32_t uniformBufferDataSize
- );
+ );
~XeRenderSystem();
XeRenderSystem(const XeRenderSystem &) = delete;
XeRenderSystem operator=(const XeRenderSystem &) = delete;
- void setUnifroms(XeFrameInfo & frameInfo);
-
- void renderGameObjects(
- int frameIndex,
- VkCommandBuffer commandBuffer,
- std::vector<XeGameObject> &gameObjects,
- void *pushConstantData,
- uint32_t pushConstantSize,
- void* uniformBufferData,
- uint32_t uniformBufferSize);
+ void loadPushConstant(void *pushConstantData, uint32_t pushConstantSize);
+ void loadUniformObject(void *uniformBufferData, uint32_t uniformBufferSize);
+ void render(XeGameObject &gameObject);
+ void stop();
private:
+
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);
+ bool boundPipeline{false};
+ bool boundDescriptor{false};
+
XeDevice& xeDevice;
+ XeRenderer& xeRenderer;
std::unique_ptr<XePipeline> xePipeline;
std::vector<std::unique_ptr<XeBuffer>> uboBuffers;
diff --git a/res/shaders/simple_shader.vert b/res/shaders/simple_shader.vert
index be802f7..55b0199 100755
--- a/res/shaders/simple_shader.vert
+++ b/res/shaders/simple_shader.vert
@@ -26,5 +26,5 @@ void main() {
float lightIntensity = AMBIENT + max(dot(normalWorldSpace, ubo.directionToLight), 0);
- fragColor = lightIntensity * color;
+ fragColor = lightIntensity * vec3(1/position.y,position.y,clamp(sin(position.x - position.z), 0, 1));
} \ No newline at end of file
diff --git a/res/shaders/simple_shader.vert.spv b/res/shaders/simple_shader.vert.spv
index 7b4a820..bba7f70 100644
--- a/res/shaders/simple_shader.vert.spv
+++ b/res/shaders/simple_shader.vert.spv
Binary files differ
diff --git a/src/first_app.cpp b/src/first_app.cpp
index e460c6b..7be857d 100755
--- a/src/first_app.cpp
+++ b/src/first_app.cpp
@@ -1,32 +1,20 @@
#include "first_app.hpp"
#include "xe_camera.hpp"
+#include "xe_engine.hpp"
#include "xe_game_object.hpp"
#include "xe_model.hpp"
+#include "xe_render_system.hpp"
#include "keyboard_movement_controller.hpp"
-
+#include "simple_renderer.hpp"
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
-
#include <array>
-#include <chrono>
-#include <cassert>
-#include <stdexcept>
-#include <iostream>
-namespace xe {
-
-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};
-};
+namespace app {
FirstApp::FirstApp() : xeEngine{WIDTH, HEIGHT, "Hello, Vulkan!"} {
loadGameObjects();
@@ -36,53 +24,23 @@ FirstApp::~FirstApp() {}
void FirstApp::run() {
- std::unique_ptr<XeRenderSystem> simpleRenderSystem = xeEngine.createRenderSystem(
- "res/shaders/simple_shader.vert.spv",
- "res/shaders/simple_shader.frag.spv",
- sizeof(PushConstant),
- sizeof(UniformBuffer));
+ SimpleRenderer renderer{xeEngine};
+
+ xeEngine.getCamera().setViewTarget(glm::vec3(-1.f, -2.f, 20.f), glm::vec3(0.f, 0.f, 2.5f));
- XeCamera camera{};
- camera.setViewTarget(glm::vec3(-1.f, -2.f, 20.f), glm::vec3(0.f, 0.f, 2.5f));
-
- auto viewerObject = XeGameObject::createGameObject();
+ auto viewerObject = xe::XeGameObject::createGameObject();
KeyboardMovementController cameraController{};
- auto currentTime = std::chrono::high_resolution_clock::now();
-
- while (!xeEngine.getWindow().shouldClose()) {
- glfwPollEvents();
+ while (xeEngine.poll()) {
- auto newTime = std::chrono::high_resolution_clock::now();
- float frameTime = std::chrono::duration<float, std::chrono::seconds::period>(newTime - currentTime).count();
- currentTime = newTime;
+ float frameTime = xeEngine.getFrameTime();
cameraController.moveInPlaneXZ(xeEngine.getWindow().getGLFWwindow(), frameTime, viewerObject);
- camera.setViewYXZ(viewerObject.transform.translation, viewerObject.transform.rotation);
-
- float aspect = xeEngine.getRenderer().getAspectRatio();
- camera.setPerspectiveProjection(glm::radians(50.f), aspect, 0.1f, 100.f);
+ xeEngine.getCamera().setViewYXZ(viewerObject.transform.translation, viewerObject.transform.rotation);
if(xeEngine.beginFrame()) {
-
- PushConstant pc{};
- pc.modelMatrix = gameObjects[0].transform.mat4();
- pc.normalMatrix = gameObjects[0].transform.normalMatrix();
-
- UniformBuffer ubo{};
- ubo.projectionView = camera.getProjection() * camera.getView();
-
- xeEngine.render(
- *simpleRenderSystem,
- gameObjects,
- &pc,
- sizeof(pc),
- &ubo,
- sizeof(ubo)
- );
-
+ renderer.render(gameObjects, xeEngine.getCamera());
xeEngine.endFrame();
-
}
}
@@ -91,13 +49,20 @@ void FirstApp::run() {
}
void FirstApp::loadGameObjects() {
- std::shared_ptr<XeModel> xeModel = xeEngine.createModel("res/models/stanford-dragon.obj");
+ std::shared_ptr<xe::XeModel> xeModel = xeEngine.loadModelFromFile("res/models/stanford-dragon.obj");
+
+ auto dragon = xe::XeGameObject::createGameObject();
+ dragon.model = xeModel;
+ dragon.transform.translation = {.0f, .0f, 2.5f};
+ dragon.transform.scale = {.5f, .5f, .5f};
+ gameObjects.push_back(std::move(dragon));
- auto cube = XeGameObject::createGameObject();
- cube.model = xeModel;
- cube.transform.translation = {.0f, .0f, 2.5f};
- cube.transform.scale = {.5f, .5f, .5f};
- gameObjects.push_back(std::move(cube));
+ auto dragon2 = xe::XeGameObject::createGameObject();
+ dragon2.model = xeModel;
+ dragon2.transform.translation = {5.0f, .0f, -1.5f};
+ dragon2.transform.rotation.y = glm::radians(90.f);
+ dragon2.transform.scale = {.35f, .35f, .35f};
+ gameObjects.push_back(std::move(dragon2));
}
} \ No newline at end of file
diff --git a/src/first_app.hpp b/src/first_app.hpp
index 081113d..d8942ab 100755
--- a/src/first_app.hpp
+++ b/src/first_app.hpp
@@ -7,11 +7,9 @@
#include <memory>
#include <vector>
-namespace xe {
+namespace app {
class FirstApp {
public:
- static constexpr int WIDTH = 800;
- static constexpr int HEIGHT = 600;
FirstApp();
~FirstApp();
@@ -22,10 +20,14 @@ class FirstApp {
void run();
private:
+
+ static constexpr int WIDTH = 800;
+ static constexpr int HEIGHT = 600;
+
void loadGameObjects();
- XeEngine xeEngine;
+ xe::XeEngine xeEngine;
- std::vector<XeGameObject> gameObjects;
+ std::vector<xe::XeGameObject> gameObjects;
};
} \ No newline at end of file
diff --git a/src/keyboard_movement_controller.cpp b/src/keyboard_movement_controller.cpp
index 6782709..325693e 100644
--- a/src/keyboard_movement_controller.cpp
+++ b/src/keyboard_movement_controller.cpp
@@ -4,9 +4,9 @@
#include <glm/geometric.hpp>
#include <limits>
-namespace xe {
+namespace app {
-void KeyboardMovementController::moveInPlaneXZ(GLFWwindow* window, float dt, XeGameObject& gameObject) {
+void KeyboardMovementController::moveInPlaneXZ(GLFWwindow* window, float dt, xe::XeGameObject& gameObject) {
glm::vec3 rotate{0};
if(glfwGetKey(window, keys.lookRight) == GLFW_PRESS) rotate.y += 1.f;
if(glfwGetKey(window, keys.lookLeft) == GLFW_PRESS) rotate.y -= 1.f;
diff --git a/src/keyboard_movement_controller.hpp b/src/keyboard_movement_controller.hpp
index b90d361..b3e3a15 100644
--- a/src/keyboard_movement_controller.hpp
+++ b/src/keyboard_movement_controller.hpp
@@ -4,7 +4,7 @@
#include "xe_window.hpp"
#include <GLFW/glfw3.h>
-namespace xe {
+namespace app {
class KeyboardMovementController {
public:
@@ -21,7 +21,7 @@ namespace xe {
int lookDown = GLFW_KEY_DOWN;
};
- void moveInPlaneXZ(GLFWwindow* window, float dt, XeGameObject& gameObject);
+ void moveInPlaneXZ(GLFWwindow* window, float dt, xe::XeGameObject& gameObject);
KeyMappings keys{};
float moveSpeed{3.f};
diff --git a/src/main.cpp b/src/main.cpp
index 30b64d9..fa0804d 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,7 +5,7 @@
#include <stdexcept>
int main() {
- xe::FirstApp app{};
+ app::FirstApp app{};
try {
app.run();
diff --git a/src/simple_renderer.cpp b/src/simple_renderer.cpp
new file mode 100644
index 0000000..b4c115a
--- /dev/null
+++ b/src/simple_renderer.cpp
@@ -0,0 +1,26 @@
+#include "simple_renderer.hpp"
+
+namespace app {
+
+SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine)
+ : xeRenderSystem{xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv", sizeof(PushConstant), sizeof(UniformBuffer)} {};
+
+void SimpleRenderer::render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera) {
+
+ UniformBuffer ubo{};
+ ubo.projectionView = xeCamera.getProjection() * xeCamera.getView();
+ xeRenderSystem.loadUniformObject(&ubo, sizeof(ubo));
+
+ for(auto &obj : gameObjects) {
+ PushConstant pc{};
+ pc.modelMatrix = obj.transform.mat4();
+ pc.normalMatrix = obj.transform.normalMatrix();
+ xeRenderSystem.loadPushConstant(&pc, sizeof(pc));
+ xeRenderSystem.render(obj);
+ }
+
+ xeRenderSystem.stop();
+
+}
+
+} \ No newline at end of file
diff --git a/src/simple_renderer.hpp b/src/simple_renderer.hpp
new file mode 100644
index 0000000..22ba0b4
--- /dev/null
+++ b/src/simple_renderer.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "xe_render_system.hpp"
+#include <string>
+
+namespace app {
+
+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};
+};
+
+class SimpleRenderer {
+
+ public:
+
+ SimpleRenderer(xe::XeEngine &xeEngine);
+
+ ~SimpleRenderer() {};
+
+ SimpleRenderer(const SimpleRenderer&) = delete;
+ SimpleRenderer operator=(const SimpleRenderer&) = delete;
+
+ void render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera);
+
+ private:
+ xe::XeRenderSystem xeRenderSystem;
+
+};
+
+} \ No newline at end of file