summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/xe_descriptors.cpp1
-rw-r--r--engine/xe_engine.cpp7
-rw-r--r--engine/xe_engine.hpp4
-rw-r--r--engine/xe_model.cpp109
-rw-r--r--engine/xe_model.hpp22
-rwxr-xr-xengine/xe_pipeline.cpp22
-rwxr-xr-xengine/xe_pipeline.hpp10
-rw-r--r--engine/xe_render_system.cpp13
-rw-r--r--engine/xe_render_system.hpp27
-rw-r--r--engine/xe_utils.hpp11
-rwxr-xr-xres/shaders/simple_shader.frag5
-rwxr-xr-xres/shaders/simple_shader.vert5
-rwxr-xr-xsrc/first_app.cpp4
-rw-r--r--src/simple_renderer.cpp5
-rw-r--r--src/simple_renderer.hpp7
15 files changed, 132 insertions, 120 deletions
diff --git a/engine/xe_descriptors.cpp b/engine/xe_descriptors.cpp
index 4840c9e..367b26e 100644
--- a/engine/xe_descriptors.cpp
+++ b/engine/xe_descriptors.cpp
@@ -2,6 +2,7 @@
#include <cassert>
#include <stdexcept>
+#include <iostream>
namespace xe {
diff --git a/engine/xe_engine.cpp b/engine/xe_engine.cpp
index 7a6df71..a4ddaea 100644
--- a/engine/xe_engine.cpp
+++ b/engine/xe_engine.cpp
@@ -35,16 +35,17 @@ std::shared_ptr<Model> Engine::loadModelFromFile(const std::string &filename) {
return Model::createModelFromFile(xeDevice, filename);
}
-std::shared_ptr<Model> Engine::loadModelFromData(std::vector<Model::Vertex> vertices, std::vector<uint32_t> indices) {
+std::shared_ptr<Model> Engine::loadModelFromData(std::vector<float> vertexData, uint32_t vertexSize, std::vector<uint32_t> indices) {
Model::Builder builder{};
- builder.vertices = vertices;
+ builder.vertexData = vertexData;
+ builder.vertexSize = vertexSize;
if(indices.size() > 0) {
builder.indices = indices;
}
return std::make_shared<Model>(xeDevice, builder);
}
-std::shared_ptr<Image> Engine::loadImage(const std::string &filename) {
+std::shared_ptr<Image> Engine::loadImageFromFile(const std::string &filename) {
return std::make_shared<Image>(xeDevice, filename);
}
diff --git a/engine/xe_engine.hpp b/engine/xe_engine.hpp
index 7f78239..aa1c774 100644
--- a/engine/xe_engine.hpp
+++ b/engine/xe_engine.hpp
@@ -26,8 +26,8 @@ class Engine {
Camera& getCamera() {return xeCamera;}
std::shared_ptr<Model> loadModelFromFile(const std::string &filename);
- std::shared_ptr<Model> loadModelFromData(std::vector<Model::Vertex> vertices, std::vector<uint32_t> indices);
- std::shared_ptr<Image> loadImage(const std::string &filename);
+ std::shared_ptr<Model> loadModelFromData(std::vector<float> vertexData, uint32_t vertexSize, std::vector<uint32_t> indices);
+ std::shared_ptr<Image> loadImageFromFile(const std::string &filename);
bool beginFrame() { return xeRenderer.beginFrame(); }
void endFrame() { xeRenderer.endFrame(); }
diff --git a/engine/xe_model.cpp b/engine/xe_model.cpp
index df210d8..48f9ad2 100644
--- a/engine/xe_model.cpp
+++ b/engine/xe_model.cpp
@@ -1,5 +1,4 @@
#include "xe_model.hpp"
-#include "xe_utils.hpp"
#define TINYOBJLOADER_IMPLEMENTATION
#include "xe_obj_loader.hpp"
@@ -10,22 +9,12 @@
#include <cassert>
#include <cstring>
#include <unordered_map>
-
-namespace std {
-template<>
-struct hash<xe::Model::Vertex> {
- size_t operator()(xe::Model::Vertex const &vertex) const {
- size_t seed = 0;
- xe::hashCombine(seed, vertex.position, vertex.normal, vertex.uv);
- return seed;
- }
-};
-}
+#include <iostream>
namespace xe {
Model::Model(Device &device, const Model::Builder &builder) : xeDevice{device} {
- createVertexBuffers(builder.vertices);
+ createVertexBuffers(builder.vertexData, builder.vertexSize);
createIndexBuffers(builder.indices);
}
@@ -37,11 +26,10 @@ std::unique_ptr<Model> Model::createModelFromFile(Device &device, const std::str
return std::make_unique<Model>(device, builder);
}
-void Model::createVertexBuffers(const std::vector<Vertex> &vertices) {
- vertexCount = static_cast<uint32_t>(vertices.size());
+void Model::createVertexBuffers(const std::vector<float> &vertexData, uint32_t vertexSize) {
+ vertexCount = static_cast<uint32_t>(vertexData.size()) / (vertexSize / 4);
assert(vertexCount >= 3 && "Vertex count must be atleast 3");
- VkDeviceSize bufferSize = sizeof(vertices[0]) * vertexCount;
- uint32_t vertexSize = sizeof(vertices[0]);
+ VkDeviceSize bufferSize = vertexData.size() * 4;
Buffer stagingBuffer {
xeDevice,
@@ -52,7 +40,7 @@ void Model::createVertexBuffers(const std::vector<Vertex> &vertices) {
};
stagingBuffer.map();
- stagingBuffer.writeToBuffer((void *)vertices.data());
+ stagingBuffer.writeToBuffer((void *)vertexData.data());
vertexBuffer = std::make_unique<Buffer>(
xeDevice,
@@ -65,16 +53,16 @@ void Model::createVertexBuffers(const std::vector<Vertex> &vertices) {
xeDevice.copyBuffer(stagingBuffer.getBuffer(), vertexBuffer->getBuffer(), bufferSize);
}
-void Model::createIndexBuffers(const std::vector<uint32_t> &indices) {
- indexCount = static_cast<uint32_t>(indices.size());
+void Model::createIndexBuffers(const std::vector<uint32_t> &indexData) {
+ indexCount = static_cast<uint32_t>(indexData.size());
hasIndexBuffer = indexCount > 0;
if (!hasIndexBuffer) {
return;
}
- VkDeviceSize bufferSize = sizeof(indices[0]) * indexCount;
- uint32_t indexSize = sizeof(indices[0]);
+ VkDeviceSize bufferSize = sizeof(indexData[0]) * indexCount;
+ uint32_t indexSize = sizeof(indexData[0]);
Buffer stagingBuffer {
xeDevice,
@@ -85,7 +73,7 @@ void Model::createIndexBuffers(const std::vector<uint32_t> &indices) {
};
stagingBuffer.map();
- stagingBuffer.writeToBuffer((void *)indices.data());
+ stagingBuffer.writeToBuffer((void *)indexData.data());
indexBuffer = std::make_unique<Buffer>(
xeDevice,
@@ -116,25 +104,6 @@ void Model::draw(VkCommandBuffer commandBuffer) {
}
}
-std::vector<VkVertexInputBindingDescription> Model::Vertex::getBindingDescriptions() {
- std::vector<VkVertexInputBindingDescription> bindingDescriptions(1);
- bindingDescriptions[0].binding = 0;
- bindingDescriptions[0].stride = sizeof(Vertex);
- bindingDescriptions[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
- return bindingDescriptions;
-}
-
-std::vector<VkVertexInputAttributeDescription> Model::Vertex::getAttributeDescriptions() {
- std::vector<VkVertexInputAttributeDescription> attributeDescptions{};
-
- attributeDescptions.push_back({0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, position)});
- attributeDescptions.push_back({1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, color)});
- attributeDescptions.push_back({2, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal)});
- attributeDescptions.push_back({3, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv)});
-
- return attributeDescptions;
-}
-
void Model::Builder::loadModel(const std::string &filepath) {
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
@@ -144,50 +113,52 @@ void Model::Builder::loadModel(const std::string &filepath) {
throw std::runtime_error(warn + err);
}
- vertices.clear();
+ vertexData.clear();
indices.clear();
+ vertexSize = 0;
+
+ bool vertex, color, normal, uvs;
- std::unordered_map<Vertex, uint32_t> uniqueVertices{};
for (const auto &shape : shapes) {
for (const auto &index : shape.mesh.indices) {
- Vertex vertex{};
if(index.vertex_index >= 0) {
- vertex.position = {
- attrib.vertices[3 * index.vertex_index + 0],
- attrib.vertices[3 * index.vertex_index + 1],
- attrib.vertices[3 * index.vertex_index + 2]
- };
+ vertexData.push_back(attrib.vertices[3 * index.vertex_index + 0]);
+ vertexData.push_back(attrib.vertices[3 * index.vertex_index + 1]);
+ vertexData.push_back(attrib.vertices[3 * index.vertex_index + 2]);
+ vertex = true;
- vertex.color = {
- attrib.colors[3 * index.vertex_index + 0],
- attrib.colors[3 * index.vertex_index + 1],
- attrib.colors[3 * index.vertex_index + 2]
- };
+ vertexData.push_back(attrib.colors[3 * index.vertex_index + 0]);
+ vertexData.push_back(attrib.colors[3 * index.vertex_index + 1]);
+ vertexData.push_back(attrib.colors[3 * index.vertex_index + 2]);
+ color = true;
}
if(index.normal_index >= 0) {
- vertex.normal = {
- attrib.normals[3 * index.normal_index + 0],
- attrib.normals[3 * index.normal_index + 1],
- attrib.normals[3 * index.normal_index + 2]
- };
+ vertexData.push_back(attrib.normals[3 * index.normal_index + 0]);
+ vertexData.push_back(attrib.normals[3 * index.normal_index + 1]);
+ vertexData.push_back(attrib.normals[3 * index.normal_index + 2]);
+ normal = true;
}
if(index.texcoord_index >= 0) {
- vertex.uv = {
- attrib.texcoords[2 * index.texcoord_index + 0],
- attrib.texcoords[2 * index.texcoord_index + 1],
- };
+ vertexData.push_back(attrib.texcoords[2 * index.texcoord_index + 0]);
+ vertexData.push_back(attrib.texcoords[2 * index.texcoord_index + 1]);
+ uvs = true;
}
- if (uniqueVertices.count(vertex) == 0) {
- uniqueVertices[vertex] = static_cast<uint32_t>(vertices.size());
- vertices.push_back(vertex);
- }
- indices.push_back(uniqueVertices[vertex]);
}
}
+
+ if(vertex)
+ vertexSize += 12;
+ if(color)
+ vertexSize += 12;
+ if(normal)
+ vertexSize += 12;
+ if(uvs)
+ vertexSize += 8;
+
}
} \ No newline at end of file
diff --git a/engine/xe_model.hpp b/engine/xe_model.hpp
index fec572f..09c5913 100644
--- a/engine/xe_model.hpp
+++ b/engine/xe_model.hpp
@@ -14,22 +14,10 @@ namespace xe {
class Model {
public:
- struct Vertex {
- glm::vec3 position;
- glm::vec3 color;
- glm::vec3 normal;
- glm::vec2 uv;
-
- static std::vector<VkVertexInputBindingDescription> getBindingDescriptions();
- static std::vector<VkVertexInputAttributeDescription> getAttributeDescriptions();
-
- bool operator==(const Vertex &other) const {
- return position == other.position && color == other.color && normal == other.normal && uv == other.uv;
- }
- };
-
struct Builder {
- std::vector<Vertex> vertices{};
+ std::vector<float> vertexData{};
+ uint32_t vertexSize;
+
std::vector<uint32_t> indices{};
void loadModel(const std::string &filepath);
@@ -47,8 +35,8 @@ class Model {
void draw(VkCommandBuffer commandBuffer);
private:
- void createVertexBuffers(const std::vector<Vertex> &vertices);
- void createIndexBuffers(const std::vector<uint32_t> &indices);
+ void createVertexBuffers(const std::vector<float> &vertexData, uint32_t vertexSize);
+ void createIndexBuffers(const std::vector<uint32_t> &indexData);
Device &xeDevice;
diff --git a/engine/xe_pipeline.cpp b/engine/xe_pipeline.cpp
index 3f407ec..633548f 100755
--- a/engine/xe_pipeline.cpp
+++ b/engine/xe_pipeline.cpp
@@ -16,9 +16,11 @@ namespace xe {
Device &device,
const std::string& vertFilepath,
const std::string& fragFilepath,
- const PipelineConfigInfo& configInfo)
- : xeDevice{device} {
- createGraphicsPipeline(vertFilepath, fragFilepath, configInfo);
+ const PipelineConfigInfo& configInfo,
+ std::vector<VkVertexInputAttributeDescription> &attributeDescptions,
+ uint32_t vertexSize
+ ) : xeDevice{device} {
+ createGraphicsPipeline(vertFilepath, fragFilepath, configInfo, attributeDescptions, vertexSize);
}
Pipeline::~Pipeline() {
@@ -48,7 +50,10 @@ namespace xe {
void Pipeline::createGraphicsPipeline(
const std::string& vertFilePath,
const std::string& fragFilepath,
- const PipelineConfigInfo& configInfo) {
+ const PipelineConfigInfo& configInfo,
+ std::vector<VkVertexInputAttributeDescription> &attributeDescptions,
+ uint32_t vertexSize
+ ) {
assert(
configInfo.pipelineLayout != VK_NULL_HANDLE &&
@@ -78,8 +83,13 @@ namespace xe {
shaderStages[1].pNext = nullptr;
shaderStages[1].pSpecializationInfo = nullptr;
- auto bindingDescriptions = Model::Vertex::getBindingDescriptions();
- auto attributeDescptions = Model::Vertex::getAttributeDescriptions();
+ VkVertexInputBindingDescription bindingDescription;
+ bindingDescription.binding = 0;
+ bindingDescription.stride = vertexSize;
+ bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+
+ std::vector<VkVertexInputBindingDescription> bindingDescriptions{bindingDescription};
+
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescptions.size());
diff --git a/engine/xe_pipeline.hpp b/engine/xe_pipeline.hpp
index cb601e0..14df508 100755
--- a/engine/xe_pipeline.hpp
+++ b/engine/xe_pipeline.hpp
@@ -33,7 +33,10 @@ class Pipeline {
Device &device,
const std::string& vertFilepath,
const std::string& fragFilepath,
- const PipelineConfigInfo& configInfo);
+ const PipelineConfigInfo& configInfo,
+ std::vector<VkVertexInputAttributeDescription> &attributeDescptions,
+ uint32_t vertexSize
+ );
~Pipeline();
Pipeline(const Pipeline&) = delete;
@@ -48,7 +51,10 @@ class Pipeline {
void createGraphicsPipeline(
const std::string& vertFilePath,
const std::string& fragFilepath,
- const PipelineConfigInfo& configInfo);
+ const PipelineConfigInfo& configInfo,
+ std::vector<VkVertexInputAttributeDescription> &attributeDescptions,
+ uint32_t vertexSize
+ );
void createShaderModule(const std::vector<char>& code, VkShaderModule* shaderModule);
diff --git a/engine/xe_render_system.cpp b/engine/xe_render_system.cpp
index 4f2aadd..cf30f24 100644
--- a/engine/xe_render_system.cpp
+++ b/engine/xe_render_system.cpp
@@ -23,7 +23,9 @@ RenderSystem::RenderSystem(
std::map<uint32_t, uint32_t> uniformBindings,
std::map<uint32_t, Image*> imageBindings,
uint32_t pushCunstantDataSize,
- bool cullingEnabled
+ bool cullingEnabled,
+ std::vector<VkVertexInputAttributeDescription> attributeDescptions,
+ uint32_t vertexSize
) : xeDevice{xeEngine.xeDevice},
xeRenderer{xeEngine.xeRenderer},
xeDescriptorPool{xeEngine.xeDescriptorPool},
@@ -35,10 +37,9 @@ RenderSystem::RenderSystem(
createUniformBuffers();
createDescriptorSets();
createPipelineLayout();
- createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag, cullingEnabled);
+ createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag, cullingEnabled, attributeDescptions, vertexSize);
}
-
RenderSystem::~RenderSystem() {
vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr);
vkDestroySampler(xeDevice.device(), textureSampler, nullptr);
@@ -164,7 +165,7 @@ void RenderSystem::createPipelineLayout() {
}
-void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled) {
+void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, std::vector<VkVertexInputAttributeDescription> attributeDescptions, uint32_t vertexSize) {
assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout");
PipelineConfigInfo pipelineConfig{};
@@ -178,7 +179,9 @@ void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std
xeDevice,
vert,
frag,
- pipelineConfig
+ pipelineConfig,
+ attributeDescptions,
+ vertexSize
);
}
diff --git a/engine/xe_render_system.hpp b/engine/xe_render_system.hpp
index 2b29642..fd5043f 100644
--- a/engine/xe_render_system.hpp
+++ b/engine/xe_render_system.hpp
@@ -11,6 +11,7 @@
#include <memory>
#include <map>
+#include <vector>
namespace xe {
@@ -21,6 +22,21 @@ class RenderSystem {
public:
Builder(Engine &xeEngine, std::string vert, std::string frag) : xeEngine{xeEngine}, vert{vert}, frag{frag} {}
+ Builder& addVertexBinding(uint32_t binding, uint32_t dimension, uint32_t offset){
+ if(dimension == 1)
+ attributeDescptions.push_back({binding, 0, VK_FORMAT_R32_SFLOAT, offset});
+ if(dimension == 2)
+ attributeDescptions.push_back({binding, 0, VK_FORMAT_R32G32_SFLOAT, offset});
+ if(dimension == 3)
+ attributeDescptions.push_back({binding, 0, VK_FORMAT_R32G32B32_SFLOAT, offset});
+ return *this;
+ }
+
+ Builder& setVertexSize(uint32_t size) {
+ vertexSize = size;
+ return *this;
+ }
+
Builder& addPushConstant(uint32_t size) {
pushCunstantDataSize = size;
return *this;
@@ -42,7 +58,7 @@ class RenderSystem {
}
std::unique_ptr<RenderSystem> build() {
- return std::make_unique<RenderSystem>(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled));
+ return std::make_unique<RenderSystem>(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled), std::move(attributeDescptions), std::move(vertexSize));
}
private:
@@ -51,6 +67,9 @@ class RenderSystem {
std::map<uint32_t, Image*> imageBindings{};
uint32_t pushCunstantDataSize{0};
+ std::vector<VkVertexInputAttributeDescription> attributeDescptions{};
+ uint32_t vertexSize;
+
std::string vert;
std::string frag;
@@ -66,7 +85,9 @@ class RenderSystem {
std::map<uint32_t, uint32_t> uniformBindings,
std::map<uint32_t, Image*> imageBindings,
uint32_t pushCunstantDataSize,
- bool cullingEnabled
+ bool cullingEnabled,
+ std::vector<VkVertexInputAttributeDescription> attributeDescptions,
+ uint32_t vertexSize
);
~RenderSystem();
@@ -89,7 +110,7 @@ class RenderSystem {
void createDescriptorSets();
void updateDescriptorSet(int frameIndex, bool allocate);
void createPipelineLayout();
- void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled);
+ void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, std::vector<VkVertexInputAttributeDescription> attributeDescptions, uint32_t vertexSize);
bool boundPipeline{false};
bool boundDescriptor{false};
diff --git a/engine/xe_utils.hpp b/engine/xe_utils.hpp
deleted file mode 100644
index 4ec88cf..0000000
--- a/engine/xe_utils.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-namespace xe {
-
-template <typename T, typename... Rest>
-void hashCombine(std::size_t& seed, const T& v, const Rest&... rest) {
- seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
- (hashCombine(seed, rest), ...);
-};
-
-} \ No newline at end of file
diff --git a/res/shaders/simple_shader.frag b/res/shaders/simple_shader.frag
index 4eaaafc..a4e2b7e 100755
--- a/res/shaders/simple_shader.frag
+++ b/res/shaders/simple_shader.frag
@@ -10,6 +10,11 @@ layout (binding = 0) uniform GlobalUbo {
vec3 directionToLight;
} ubo;
+layout (binding = 2) uniform Deez {
+ mat4 projectionViewMatrix;
+ vec3 directionToLight;
+} deez;
+
layout (binding = 1) uniform sampler2D texSampler;
layout(push_constant) uniform Push {
diff --git a/res/shaders/simple_shader.vert b/res/shaders/simple_shader.vert
index a61fa0b..04b603e 100755
--- a/res/shaders/simple_shader.vert
+++ b/res/shaders/simple_shader.vert
@@ -13,6 +13,11 @@ layout (binding = 0) uniform GlobalUbo {
vec3 directionToLight;
} ubo;
+layout (binding = 2) uniform Deez {
+ mat4 projectionViewMatrix;
+ vec3 directionToLight;
+} deez;
+
layout (push_constant) uniform Push {
mat4 modelMatrix;
mat4 normalMatrix;
diff --git a/src/first_app.cpp b/src/first_app.cpp
index 5b2d23d..3de0a0b 100755
--- a/src/first_app.cpp
+++ b/src/first_app.cpp
@@ -27,8 +27,8 @@ FirstApp::~FirstApp() {}
void FirstApp::run() {
- std::shared_ptr<xe::Image> image = xeEngine.loadImage("res/image/texture.png");
- std::shared_ptr<xe::Image> image2 = xeEngine.loadImage("res/image/ltt.");
+ std::shared_ptr<xe::Image> image = xeEngine.loadImageFromFile("res/image/texture.png");
+ std::shared_ptr<xe::Image> image2 = xeEngine.loadImageFromFile("res/image/scaly.png");
SimpleRenderer renderer{xeEngine, image.get()};
diff --git a/src/simple_renderer.cpp b/src/simple_renderer.cpp
index 43c933d..82acb46 100644
--- a/src/simple_renderer.cpp
+++ b/src/simple_renderer.cpp
@@ -7,6 +7,11 @@ namespace app {
SimpleRenderer::SimpleRenderer(xe::Engine &xeEngine, xe::Image *xeImage) {
xeRenderSystem = xe::RenderSystem::Builder(xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv")
+ .addVertexBinding(0, 3, 0)
+ .addVertexBinding(1, 3, 12)
+ .addVertexBinding(2, 3, 24)
+ .addVertexBinding(3, 2, 36)
+ .setVertexSize(sizeof(Vertex))
.addPushConstant(sizeof(PushConstant))
.addUniformBinding(0, sizeof(UniformBuffer))
.addTextureBinding(1, xeImage)
diff --git a/src/simple_renderer.hpp b/src/simple_renderer.hpp
index 59c1e60..e0e9a93 100644
--- a/src/simple_renderer.hpp
+++ b/src/simple_renderer.hpp
@@ -15,6 +15,13 @@ struct PushConstant {
alignas(16) glm::mat4 normalMatrix{1.f};
};
+struct Vertex {
+ glm::vec3 position;
+ glm::vec3 color;
+ glm::vec3 normal;
+ glm::vec2 uv;
+};
+
class SimpleRenderer {
public: