diff --git a/assets/shaders/helloworld.vert.spv b/assets/shaders/helloworld.vert.spv
index 7d2aebb..4062a52 100644
Binary files a/assets/shaders/helloworld.vert.spv and b/assets/shaders/helloworld.vert.spv differ
diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt
index f1146f3..eedab98 100644
--- a/frontend/CMakeLists.txt
+++ b/frontend/CMakeLists.txt
@@ -13,11 +13,12 @@ project (EEfrontend)
# List sources
-set(HEADERS "Engine.hpp" "Renderer.hpp" "FileSystem.hpp" "compile_config.hpp" "AssetManager.hpp" "AssetData.hpp" "PipelineFactory.hpp")
-set(SOURCES "main.cpp" "Engine.cpp" "Renderer.cpp" "FileSystem.cpp" "AssetManager.cpp" "AssetData.cpp" "PipelineFactory.cpp")
-
-list(TRANSFORM HEADERS PREPEND "include/")
-list(TRANSFORM SOURCES PREPEND "src/")
+file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
+ "src/*.cpp"
+ "src/*.c"
+ "include/*.hpp"
+ "include/*.h"
+)
# Find dependencies
@@ -30,7 +31,7 @@ find_package(RmlUi CONFIG REQUIRED)
# Link library
-add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES})
+add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} PUBLIC utils)
diff --git a/frontend/include/AssetData.hpp b/frontend/include/AssetData.hpp
index bf4f427..32886f4 100644
--- a/frontend/include/AssetData.hpp
+++ b/frontend/include/AssetData.hpp
@@ -29,4 +29,10 @@ struct AssetMaterial : AssetData
uint32_t fragmentShaderAssetID;
uint32_t renderType;
uint32_t renderStage;
+
+ // Vertex shader params
+ //
+
+ // Fragment shader params
+ //
};
\ No newline at end of file
diff --git a/frontend/include/GPU_Types/GPU_BaseTypes.hpp b/frontend/include/GPU_Types/GPU_BaseTypes.hpp
new file mode 100644
index 0000000..7866bdc
--- /dev/null
+++ b/frontend/include/GPU_Types/GPU_BaseTypes.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#define ATTRIBUTE_FORMAT_VEC2 VK_FORMAT_R32G32_SFLOAT
+#define ATTRIBUTE_FORMAT_VEC3 VK_FORMAT_R32G32B32_SFLOAT
+#define ATTRIBUTE_FORMAT_VEC4 VK_FORMAT_R32G32B32A32_SFLOAT
+
+struct GPU_Transform
+{
+ glm::vec3 pos = glm::vec3(0.0f, 0.0f, 0.0f);
+ glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
+};
+
+struct GPU_Vertex
+{
+ glm::vec2 pos;
+ glm::vec3 color;
+
+ static std::array GetAttributes();
+};
+
+struct GPU_BufferSlot
+{
+ size_t position;
+ size_t size;
+};
+
+template struct GPU_Buffer
+{
+ T *data;
+ size_t size;
+ const size_t ELEMENT_SIZE;
+ std::vector freeSlots;
+
+ GPU_Buffer();
+ GPU_BufferSlot* FindFreeSlot(size_t size);
+ size_t Write(const T *elements, size_t elementsCount);
+ // void Clear(GPU_BufferSlot range);
+};
+
+
+
+
+// Template definitions
+
+template GPU_Buffer::GPU_Buffer() : ELEMENT_SIZE(sizeof(T))
+{
+ freeSlots.push_back({.position = 0, .size = size});
+}
+
+template GPU_BufferSlot* GPU_Buffer::FindFreeSlot(size_t size)
+{
+ for (auto i = freeSlots.rbegin(); i != freeSlots.rend(); i++)
+ {
+ if (i->size >= size)
+ return &(*i);
+ }
+ return nullptr;
+}
+
+template size_t GPU_Buffer::Write(const T *elements, size_t elementsCount)
+{
+ GPU_BufferSlot *slot = FindFreeSlot(elementsCount);
+ if (slot == nullptr) return 0;
+
+ memcpy(data + slot->position, elements, elementsCount * ELEMENT_SIZE);
+
+ slot->size -= elementsCount;
+ slot->position += elementsCount;
+ if (slot->size == 0)
+ freeSlots.pop_back();
+
+ return slot->position - elementsCount;
+}
+
+// template void GPU_Buffer::Clear(GPU_BufferSlot range)
+// {
+// freeSlots.push_back(range);
+// //TODO: insert sorted by pos and combine intersections
+// }
\ No newline at end of file
diff --git a/frontend/include/GPU_Types/GPU_RenderUBO.hpp b/frontend/include/GPU_Types/GPU_RenderUBO.hpp
new file mode 100644
index 0000000..97830d2
--- /dev/null
+++ b/frontend/include/GPU_Types/GPU_RenderUBO.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "GPU_BaseTypes.hpp"
+#include
+
+struct GPU_GlobalUBO
+{
+ glm::mat4 view;
+ glm::mat4 proj;
+ float time;
+};
+
+struct GPU_TranformUBO
+{
+ glm::mat4 model;
+
+ void Update(const GPU_Transform &tranform);
+};
\ No newline at end of file
diff --git a/frontend/include/PipelineFactory.hpp b/frontend/include/PipelineFactory.hpp
index 16db0db..cf3aa24 100644
--- a/frontend/include/PipelineFactory.hpp
+++ b/frontend/include/PipelineFactory.hpp
@@ -38,6 +38,10 @@ struct PipelineConfig
VkViewport defaultViewport;
VkRect2D defaultScissors;
std::vector dynamicStates;
+
+ std::vector uniforms;
+ int vertexBindingsCount, fragmentBindingsCount;
+ VkDescriptorSetLayoutCreateInfo uniformsConfig;
VkGraphicsPipelineCreateInfo pipelineConfig;
@@ -48,6 +52,7 @@ struct Pipeline
{
VkPipeline instance;
VkPipelineLayout layout;
+ VkDescriptorSetLayout uniformsLayout;
VkViewport viewport;
VkRect2D scissors;
};
diff --git a/frontend/include/Renderer.hpp b/frontend/include/Renderer.hpp
index 69cd2a8..90bd683 100644
--- a/frontend/include/Renderer.hpp
+++ b/frontend/include/Renderer.hpp
@@ -2,14 +2,14 @@
#include
#include
#include
-#include
#include
#include
#include
#define GLFW_INCLUDE_VULKAN
#include
-#include
+
+#include "GPU_Types/GPU_BaseTypes.hpp"
#include "PipelineFactory.hpp"
@@ -19,10 +19,6 @@
#define VALIDATION_LAYER
#endif
-#define ATTRIBUTE_FORMAT_VEC2 VK_FORMAT_R32G32_SFLOAT
-#define ATTRIBUTE_FORMAT_VEC3 VK_FORMAT_R32G32B32_SFLOAT
-#define ATTRIBUTE_FORMAT_VEC4 VK_FORMAT_R32G32B32A32_SFLOAT
-
// GPU properties priority for selection
#define GPU_DISCRETE_PRIORITY 1000
#define GPU_GRAPHICS_WITH_PRESENT_PRIORITY 500
@@ -36,84 +32,6 @@
#define INDICES_SIZE uint16_t
#define INDICES_SIZE_VK VK_INDEX_TYPE_UINT16
-struct Transform
-{
- float x = 0.0f, y = 0.0f;
- float scaleX = 1.0f, scaleY = 1.0f, scaleZ = 1.0f;
-};
-
-struct GPU_Vertex
-{
- glm::vec2 pos;
- glm::vec3 color;
-
- static std::array GetAttributes()
- {
- VkVertexInputAttributeDescription posAttribute = {
- .location = 0,
- .binding = 0,
- .format = ATTRIBUTE_FORMAT_VEC2,
- .offset = offsetof(GPU_Vertex, pos)
- };
- VkVertexInputAttributeDescription colorAttribute = {
- .location = 1,
- .binding = 0,
- .format = ATTRIBUTE_FORMAT_VEC3,
- .offset = offsetof(GPU_Vertex, color)
- };
-
- return {posAttribute, colorAttribute};
- }
-};
-
-struct GPU_BufferSlot
-{
- size_t position;
- size_t size;
-};
-
-//TODO: move methods definition to the end of file
-template struct GPU_Buffer
-{
- T *data;
- size_t size;
- const size_t ELEMENT_SIZE;
- std::vector freeSlots;
-
- GPU_Buffer() : ELEMENT_SIZE(sizeof(T)) {freeSlots.push_back({.position = 0, .size = size});}
-
- GPU_BufferSlot* FindFreeSlot(size_t size)
- {
- for (auto i = freeSlots.rbegin(); i != freeSlots.rend(); i++)
- {
- if (i->size >= size)
- return &(*i);
- }
- return nullptr;
- }
-
- size_t Write(const T *elements, size_t elementsCount)
- {
- GPU_BufferSlot *slot = FindFreeSlot(elementsCount);
- if (slot == nullptr) return 0;
-
- memcpy(data + slot->position, elements, elementsCount * ELEMENT_SIZE);
-
- slot->size -= elementsCount;
- slot->position += elementsCount;
- if (slot->size == 0)
- freeSlots.pop_back();
-
- return slot->position - elementsCount;
- }
-
- // void Clear(GPU_BufferSlot range)
- // {
- // freeSlots.push_back(range);
- // //TODO: insert sorted by pos and combine intersections
- // }
-};
-
struct Mesh
{
size_t verticesBufferPosition = 0;
@@ -122,19 +40,27 @@ struct Mesh
std::vector indices;
};
+struct MaterialParams
+{
+ VkDescriptorSet descriptors;
+ //TODO: push-constants
+
+ void Set(const char** param, const char** property = nullptr);
+};
+
struct RenderObject
{
uint32_t engineId = UINT32_MAX;
// Multiple transforms for batching
- std::vector transforms;
+ std::vector transforms;
uint8_t depth = 0;
Mesh mesh;
bool isUI = false;
//TODO: texture
AssetMaterial &material;
- //TODO: materialParams (uniforms)
+ MaterialParams materialParams;
};
bool operator < (const RenderObject& lhs, const RenderObject& rhs);
@@ -268,6 +194,10 @@ private:
VkBuffer stagingWorldIndices;
VkBuffer uiVertices;
VkBuffer uiIndices;
+ std::vector worldUniformsMemory;
+ std::vector worldUniforms;
+ std::vector uiUniformsMemory;
+ std::vector uiUniforms;
std::vector graphicsCommandBuffers;
std::vector transferCommandBuffers;
std::vector frames;
diff --git a/frontend/src/GPU_Types.cpp b/frontend/src/GPU_Types.cpp
new file mode 100644
index 0000000..f815be6
--- /dev/null
+++ b/frontend/src/GPU_Types.cpp
@@ -0,0 +1,29 @@
+#include "GPU_Types/GPU_BaseTypes.hpp"
+#include "GPU_Types/GPU_RenderUBO.hpp"
+
+#include
+
+std::array GPU_Vertex::GetAttributes()
+{
+ VkVertexInputAttributeDescription posAttribute = {
+ .location = 0,
+ .binding = 0,
+ .format = ATTRIBUTE_FORMAT_VEC2,
+ .offset = offsetof(GPU_Vertex, pos)
+ };
+ VkVertexInputAttributeDescription colorAttribute = {
+ .location = 1,
+ .binding = 0,
+ .format = ATTRIBUTE_FORMAT_VEC3,
+ .offset = offsetof(GPU_Vertex, color)
+ };
+
+ return {posAttribute, colorAttribute};
+}
+
+void GPU_TranformUBO::Update(const GPU_Transform &transform)
+{
+ model = glm::mat4(1.0f);
+ model = glm::translate(model, transform.pos);
+ model = glm::scale(model, transform.scale);
+}
\ No newline at end of file
diff --git a/frontend/src/PipelineFactory.cpp b/frontend/src/PipelineFactory.cpp
index 83e729b..daf7871 100644
--- a/frontend/src/PipelineFactory.cpp
+++ b/frontend/src/PipelineFactory.cpp
@@ -10,6 +10,7 @@ PipelineConfig PipelineConfig::Copy() const
copy.viewportStateConfig.pScissors = ©.defaultScissors;
copy.dynamicStateConfig.pDynamicStates = copy.dynamicStates.data();
copy.colorBlendConfig.pAttachments = copy.colorBlendAttachmentConfigs.data();
+ copy.uniformsConfig.pBindings = copy.uniforms.data();
copy.pipelineConfig.pVertexInputState = ©.vertexInputConfig;
copy.pipelineConfig.pInputAssemblyState = ©.inputAssemblyConfig;
copy.pipelineConfig.pViewportState = ©.viewportStateConfig;
@@ -43,6 +44,20 @@ PipelineFactory::PipelineFactory(const PipelineBinding &binding) :
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
});
+ basePipelineConfig.uniforms.push_back({
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
+ .pImmutableSamplers = nullptr
+ }); // GPU_GlobalUBO
+
+ basePipelineConfig.uniforms.push_back({
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
+ .pImmutableSamplers = nullptr
+ }); // GPU_TransformUBO
+
basePipelineConfig.vertexInputConfig = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.pNext = nullptr,
@@ -89,11 +104,16 @@ PipelineFactory::PipelineFactory(const PipelineBinding &binding) :
.pDynamicStates = basePipelineConfig.dynamicStates.data()
};
+ basePipelineConfig.uniformsConfig = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+ .bindingCount = static_cast(basePipelineConfig.uniforms.size()),
+ .pBindings = basePipelineConfig.uniforms.data()
+ };
+
basePipelineConfig.pipelineLayoutConfig = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
- .setLayoutCount = 0, //TODO: vector
- .pSetLayouts = nullptr,
+ .setLayoutCount = 1,
.pushConstantRangeCount = 0,
.pPushConstantRanges = nullptr
};
@@ -158,6 +178,8 @@ Pipeline& PipelineFactory::Get(const AssetMaterial &material)
void PipelineFactory::Create(const AssetMaterial &material, const VkRenderPass &renderPass, const uint32_t &flags)
{
+ VkResult vkResult;
+
Pipeline newPipeline {};
Pipeline *result = &basePipeline;
@@ -172,16 +194,6 @@ void PipelineFactory::Create(const AssetMaterial &material, const VkRenderPass &
result = &newPipeline;
config->pipelineConfig.basePipelineHandle = basePipeline.instance;
}
-
- VkResult vkResult = vkCreatePipelineLayout(
- device,
- &config->pipelineLayoutConfig,
- nullptr,
- &result->layout
- );
- if (vkResult != VK_SUCCESS)
- LOG(CRITICAL, "Failed to create pipeline layout");
- config->pipelineConfig.layout = result->layout;
// Configure shaders
AssetHandle shaderHandle;
@@ -213,6 +225,13 @@ void PipelineFactory::Create(const AssetMaterial &material, const VkRenderPass &
.pSpecializationInfo = nullptr
});
+ VkDescriptorSetLayoutBinding baseBinding {
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 1,
+ .pImmutableSamplers = nullptr
+ };
+ baseBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+
// Fragment
VkShaderModule fragmentModule;
shaderHandle = Engine::assetManager->Find(material.fragmentShaderAssetID);
@@ -235,6 +254,26 @@ void PipelineFactory::Create(const AssetMaterial &material, const VkRenderPass &
.pSpecializationInfo = nullptr
});
+ baseBinding.binding = 0;
+ baseBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+
+ //
+
+ vkResult = vkCreateDescriptorSetLayout(device, &config->uniformsConfig, nullptr, &result->uniformsLayout);
+ if (vkResult != VK_SUCCESS)
+ LOG(CRITICAL, "Failed to create uniforms layout");
+ config->pipelineLayoutConfig.pSetLayouts = &result->uniformsLayout;
+
+ vkResult = vkCreatePipelineLayout(
+ device,
+ &config->pipelineLayoutConfig,
+ nullptr,
+ &result->layout
+ );
+ if (vkResult != VK_SUCCESS)
+ LOG(CRITICAL, "Failed to create pipeline layout");
+ config->pipelineConfig.layout = result->layout;
+
config->pipelineConfig.stageCount = static_cast(stagesConfigs.size());
config->pipelineConfig.pStages = stagesConfigs.data();
config->pipelineConfig.renderPass = renderPass;
@@ -265,9 +304,11 @@ PipelineFactory::~PipelineFactory()
{
vkDestroyPipeline(device, basePipeline.instance, nullptr);
vkDestroyPipelineLayout(device, basePipeline.layout, nullptr);
+ vkDestroyDescriptorSetLayout(device, basePipeline.uniformsLayout, nullptr);
for (auto &item : pipelines)
{
vkDestroyPipeline(device, item.second.instance, nullptr);
vkDestroyPipelineLayout(device, item.second.layout, nullptr);
+ vkDestroyDescriptorSetLayout(device, item.second.uniformsLayout, nullptr);
}
}
\ No newline at end of file
diff --git a/frontend/src/main.cpp b/frontend/src/main.cpp
index a22dc9b..446eea9 100644
--- a/frontend/src/main.cpp
+++ b/frontend/src/main.cpp
@@ -48,7 +48,7 @@ int main(int argc, char **argv)
// Test render obj
RenderObject triangle {
- .transforms = {{.x = 0, .y = 0}},
+ .transforms = {{.pos = {0.0f, 0.0f, 0.0f}}},
.mesh = {
.vertices = {
{.pos = {-0.5f, -0.5f}, .color = {0.0f, 0.0f, 0.0f}},
@@ -61,7 +61,7 @@ int main(int argc, char **argv)
.material = baseMaterial,
};
RenderObject rect {
- .transforms = {{.x = 0, .y = 0}},
+ .transforms = {{.pos = {0.0f, 0.0f, 0.0f}}},
.mesh = {
.vertices = {
{.pos = {-0.5f, -0.5f}, .color = {1.0f, 0.0f, 0.0f}},
diff --git a/sdk/shaders/helloworld/helloworld.vert b/sdk/shaders/helloworld/helloworld.vert
index 92a086e..6ea328c 100644
--- a/sdk/shaders/helloworld/helloworld.vert
+++ b/sdk/shaders/helloworld/helloworld.vert
@@ -1,12 +1,21 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
+layout(binding = 0) uniform Global {
+ mat4 view;
+ mat4 proj;
+} global;
+
+layout(binding = 1) uniform Transform {
+ mat4 model;
+} transform;
+
layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor;
void main() {
- gl_Position = vec4(inPosition, 0.0, 1.0);
+ gl_Position = global.proj * global.view * transform.model * vec4(inPosition, 0.0, 1.0);
fragColor = inColor;
}
\ No newline at end of file