diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index 399412a..72a6a62 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -194,6 +194,7 @@ + @@ -233,6 +234,7 @@ + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index a2f227f..92cb79d 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -123,6 +123,9 @@ Source Files + + Source Files + @@ -236,6 +239,9 @@ Header Files + + Header Files + diff --git a/CopiumEngine/res/shaders/passthrough.frag b/CopiumEngine/res/shaders/passthrough.frag index 886651e..f09ade6 100644 --- a/CopiumEngine/res/shaders/passthrough.frag +++ b/CopiumEngine/res/shaders/passthrough.frag @@ -1,11 +1,12 @@ #version 450 layout(set = 0, binding = 0) uniform sampler2D texSampler; -layout(location = 0) in vec2 fragTexCoord; + +layout(location = 0) in vec2 inTexCoord; layout(location = 0) out vec4 outColor; void main() { - outColor = texture(texSampler, fragTexCoord); + outColor = texture(texSampler, inTexCoord); } \ No newline at end of file diff --git a/CopiumEngine/res/shaders/passthrough.vert b/CopiumEngine/res/shaders/passthrough.vert index 7ef441a..17f81cc 100644 --- a/CopiumEngine/res/shaders/passthrough.vert +++ b/CopiumEngine/res/shaders/passthrough.vert @@ -2,10 +2,10 @@ layout(location = 0) in vec2 inPosition; -layout(location = 0) out vec2 fragTexCoord; +layout(location = 0) out vec2 outTexCoord; void main() { gl_Position = vec4(inPosition * 0.5, 0.999, 1.0); - fragTexCoord = inPosition * 0.5 + 0.5; + outTexCoord = inPosition * 0.5 + 0.5; } \ No newline at end of file diff --git a/CopiumEngine/res/shaders/renderer.frag b/CopiumEngine/res/shaders/renderer.frag index 841cf80..5c39fe3 100644 --- a/CopiumEngine/res/shaders/renderer.frag +++ b/CopiumEngine/res/shaders/renderer.frag @@ -2,51 +2,51 @@ layout(set = 0, binding = 0) uniform sampler2D texSamplers[32]; -layout(location = 0) in vec3 fragColor; -layout(location = 1) in vec2 fragTexCoord; -layout(location = 2) in flat int fragTexIndex; +layout(location = 0) in vec3 inColor; +layout(location = 1) in vec2 inTexCoord; +layout(location = 2) in flat int inTexIndex; layout(location = 0) out vec4 outColor; vec4 TextureColor() { - if(fragTexIndex == 0) return texture(texSamplers[0], fragTexCoord); - if(fragTexIndex == 1) return texture(texSamplers[1], fragTexCoord); - if(fragTexIndex == 2) return texture(texSamplers[2], fragTexCoord); - if(fragTexIndex == 3) return texture(texSamplers[3], fragTexCoord); - if(fragTexIndex == 4) return texture(texSamplers[4], fragTexCoord); - if(fragTexIndex == 5) return texture(texSamplers[5], fragTexCoord); - if(fragTexIndex == 6) return texture(texSamplers[6], fragTexCoord); - if(fragTexIndex == 7) return texture(texSamplers[7], fragTexCoord); - if(fragTexIndex == 8) return texture(texSamplers[8], fragTexCoord); - if(fragTexIndex == 9) return texture(texSamplers[9], fragTexCoord); - if(fragTexIndex == 10) return texture(texSamplers[10], fragTexCoord); - if(fragTexIndex == 11) return texture(texSamplers[11], fragTexCoord); - if(fragTexIndex == 12) return texture(texSamplers[12], fragTexCoord); - if(fragTexIndex == 13) return texture(texSamplers[13], fragTexCoord); - if(fragTexIndex == 14) return texture(texSamplers[14], fragTexCoord); - if(fragTexIndex == 15) return texture(texSamplers[15], fragTexCoord); - if(fragTexIndex == 16) return texture(texSamplers[16], fragTexCoord); - if(fragTexIndex == 17) return texture(texSamplers[17], fragTexCoord); - if(fragTexIndex == 18) return texture(texSamplers[18], fragTexCoord); - if(fragTexIndex == 19) return texture(texSamplers[19], fragTexCoord); - if(fragTexIndex == 20) return texture(texSamplers[20], fragTexCoord); - if(fragTexIndex == 21) return texture(texSamplers[21], fragTexCoord); - if(fragTexIndex == 22) return texture(texSamplers[22], fragTexCoord); - if(fragTexIndex == 23) return texture(texSamplers[23], fragTexCoord); - if(fragTexIndex == 24) return texture(texSamplers[24], fragTexCoord); - if(fragTexIndex == 25) return texture(texSamplers[25], fragTexCoord); - if(fragTexIndex == 26) return texture(texSamplers[26], fragTexCoord); - if(fragTexIndex == 27) return texture(texSamplers[27], fragTexCoord); - if(fragTexIndex == 28) return texture(texSamplers[28], fragTexCoord); - if(fragTexIndex == 29) return texture(texSamplers[29], fragTexCoord); - if(fragTexIndex == 30) return texture(texSamplers[30], fragTexCoord); - if(fragTexIndex == 31) return texture(texSamplers[31], fragTexCoord); + if(inTexIndex == 0) return texture(texSamplers[0], inTexCoord); + if(inTexIndex == 1) return texture(texSamplers[1], inTexCoord); + if(inTexIndex == 2) return texture(texSamplers[2], inTexCoord); + if(inTexIndex == 3) return texture(texSamplers[3], inTexCoord); + if(inTexIndex == 4) return texture(texSamplers[4], inTexCoord); + if(inTexIndex == 5) return texture(texSamplers[5], inTexCoord); + if(inTexIndex == 6) return texture(texSamplers[6], inTexCoord); + if(inTexIndex == 7) return texture(texSamplers[7], inTexCoord); + if(inTexIndex == 8) return texture(texSamplers[8], inTexCoord); + if(inTexIndex == 9) return texture(texSamplers[9], inTexCoord); + if(inTexIndex == 10) return texture(texSamplers[10], inTexCoord); + if(inTexIndex == 11) return texture(texSamplers[11], inTexCoord); + if(inTexIndex == 12) return texture(texSamplers[12], inTexCoord); + if(inTexIndex == 13) return texture(texSamplers[13], inTexCoord); + if(inTexIndex == 14) return texture(texSamplers[14], inTexCoord); + if(inTexIndex == 15) return texture(texSamplers[15], inTexCoord); + if(inTexIndex == 16) return texture(texSamplers[16], inTexCoord); + if(inTexIndex == 17) return texture(texSamplers[17], inTexCoord); + if(inTexIndex == 18) return texture(texSamplers[18], inTexCoord); + if(inTexIndex == 19) return texture(texSamplers[19], inTexCoord); + if(inTexIndex == 20) return texture(texSamplers[20], inTexCoord); + if(inTexIndex == 21) return texture(texSamplers[21], inTexCoord); + if(inTexIndex == 22) return texture(texSamplers[22], inTexCoord); + if(inTexIndex == 23) return texture(texSamplers[23], inTexCoord); + if(inTexIndex == 24) return texture(texSamplers[24], inTexCoord); + if(inTexIndex == 25) return texture(texSamplers[25], inTexCoord); + if(inTexIndex == 26) return texture(texSamplers[26], inTexCoord); + if(inTexIndex == 27) return texture(texSamplers[27], inTexCoord); + if(inTexIndex == 28) return texture(texSamplers[28], inTexCoord); + if(inTexIndex == 29) return texture(texSamplers[29], inTexCoord); + if(inTexIndex == 30) return texture(texSamplers[30], inTexCoord); + if(inTexIndex == 31) return texture(texSamplers[31], inTexCoord); return vec4(1, 1, 1, 1); } -void main() { - outColor = vec4(fragColor, 1.0) * TextureColor(); - // outColor = vec4(fragTexCoord, 0.0, 1.0); +void main() +{ + outColor = vec4(inColor, 1.0) * TextureColor(); } diff --git a/CopiumEngine/res/shaders/renderer.vert b/CopiumEngine/res/shaders/renderer.vert index bd7ec17..8f4a857 100644 --- a/CopiumEngine/res/shaders/renderer.vert +++ b/CopiumEngine/res/shaders/renderer.vert @@ -9,7 +9,8 @@ layout(location = 0) out vec3 fragColor; layout(location = 1) out vec2 fragTexCoord; layout(location = 2) out int fragTexIndex; -void main() { +void main() +{ gl_Position = vec4(inPosition, 1.0); fragColor = inColor; fragTexCoord = inTexCoord; diff --git a/CopiumEngine/res/shaders/shader.frag b/CopiumEngine/res/shaders/shader.frag index 5b6e065..0a7d88b 100644 --- a/CopiumEngine/res/shaders/shader.frag +++ b/CopiumEngine/res/shaders/shader.frag @@ -2,14 +2,15 @@ layout(set = 0, binding = 1) uniform sampler2D texSampler; -layout(location = 0) in vec3 fragColor; -layout(location = 1) in vec2 fragTexCoord; -layout(location = 2) in vec3 fragPosition; -layout(location = 3) in vec3 fragLightPos; +layout(location = 0) in vec3 inColor; +layout(location = 1) in vec2 inTexCoord; +layout(location = 2) in vec3 inPosition; +layout(location = 3) in vec3 inLightPos; layout(location = 0) out vec4 outColor; -void main() { - float scale = 0.45 + max(dot(vec3(0, 1, 0), normalize(fragLightPos - fragPosition)), 0.0); - outColor = vec4(fragColor, 1.0) * texture(texSampler, fragTexCoord) * scale; +void main() +{ + float scale = 0.45 + max(dot(vec3(0, 1, 0), normalize(inLightPos - inPosition)), 0.0); + outColor = vec4(inColor, 1.0) * texture(texSampler, inTexCoord) * scale; } diff --git a/CopiumEngine/res/shaders/shader.vert b/CopiumEngine/res/shaders/shader.vert index 86e76e9..02db8af 100644 --- a/CopiumEngine/res/shaders/shader.vert +++ b/CopiumEngine/res/shaders/shader.vert @@ -12,15 +12,16 @@ layout(location = 0) in vec3 inPosition; layout(location = 1) in vec3 inColor; layout(location = 2) in vec2 inTexCoord; -layout(location = 0) out vec3 fragColor; -layout(location = 1) out vec2 fragTexCoord; -layout(location = 2) out vec3 fragPosition; -layout(location = 3) out vec3 fragLightPos; +layout(location = 0) out vec3 outColor; +layout(location = 1) out vec2 outTexCoord; +layout(location = 2) out vec3 outPosition; +layout(location = 3) out vec3 outLightPos; -void main() { +void main() +{ gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0); - fragColor = inColor; - fragTexCoord = inTexCoord; - fragPosition = vec3(ubo.model * vec4(inPosition, 1.0)); - fragLightPos = ubo.lightPos; + outColor = inColor; + outTexCoord = inTexCoord; + outPosition = vec3(ubo.model * vec4(inPosition, 1.0)); + outLightPos = ubo.lightPos; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Application.cpp b/CopiumEngine/src/copium/core/Application.cpp index 58c4e5f..6f1388c 100644 --- a/CopiumEngine/src/copium/core/Application.cpp +++ b/CopiumEngine/src/copium/core/Application.cpp @@ -29,9 +29,9 @@ namespace Copium const std::vector verticesPassthrough = { VertexPassthrough{{-1.0f, -1.0f}}, - VertexPassthrough{{ 1.0f, -1.0f}}, - VertexPassthrough{{ 1.0f, 1.0f}}, VertexPassthrough{{-1.0f, 1.0f}}, + VertexPassthrough{{ 1.0f, 1.0f}}, + VertexPassthrough{{ 1.0f, -1.0f}}, }; const std::vector indicesPassthrough = { @@ -69,7 +69,7 @@ namespace Copium if (framebuffer->GetWidth() != vulkan->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != vulkan->GetSwapChain().GetExtent().height) { framebuffer->Resize(vulkan->GetSwapChain().GetExtent().width / 8, vulkan->GetSwapChain().GetExtent().height / 8); - descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0); + descriptorSetPassthrough->SetSampler(framebuffer->GetColorAttachment(), 0); } if (!vulkan->GetSwapChain().BeginPresent()) @@ -113,26 +113,21 @@ namespace Copium descriptorPool = std::make_unique(*vulkan); descriptorSet = std::make_unique(*vulkan, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0)); - descriptorSet->AddUniform(*shaderUniformBuffer, 0); - descriptorSet->AddSampler(*texture2D, 1); + descriptorSet->SetUniformBuffer(*shaderUniformBuffer, 0); + descriptorSet->SetSampler(*texture2D, 1); descriptorSetPassthrough = std::make_unique(*vulkan, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0)); - descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0); + descriptorSetPassthrough->SetSampler(framebuffer->GetColorAttachment(), 0); } void Application::InitializeGraphicsPipeline() { PipelineCreator creator{framebuffer->GetRenderPass(), "res/shaders/shader.vert", "res/shaders/shader.frag"}; - creator.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT); - creator.AddDescriptorSetLayoutBinding(0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT); creator.SetVertexDescriptor(Vertex::GetDescriptor()); - creator.SetCullMode(VK_CULL_MODE_NONE); graphicsPipeline = std::make_unique(*vulkan, creator); PipelineCreator creatorPassthrough{vulkan->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"}; - creatorPassthrough.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT); creatorPassthrough.SetVertexDescriptor(VertexPassthrough::GetDescriptor()); - creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE); graphicsPipelinePassthrough = std::make_unique(*vulkan, creatorPassthrough); } diff --git a/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp b/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp index bb5178d..41ce86d 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp +++ b/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp @@ -16,7 +16,7 @@ namespace Copium descriptorPool.FreeDescriptorSets(descriptorSets); } - void DescriptorSet::AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding) + void DescriptorSet::SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding) { for (size_t i = 0; i < descriptorSets.size(); ++i) { VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i); @@ -35,15 +35,15 @@ namespace Copium } } - void DescriptorSet::AddSampler(const Sampler& sampler, uint32_t binding, int arrayIndex) + void DescriptorSet::SetSampler(const Sampler& sampler, uint32_t binding, int arrayIndex) { for (size_t i = 0; i < descriptorSets.size(); ++i) { - AddSampler(sampler, binding, i, arrayIndex); + SetSampler(sampler, binding, i, arrayIndex); } } - void DescriptorSet::AddSampler(const Sampler& sampler, uint32_t binding, int index, int arrayIndex) + void DescriptorSet::SetSampler(const Sampler& sampler, uint32_t binding, int index, int arrayIndex) { CP_ASSERT(index >= 0 && index < descriptorSets.size(), "AddSampler : index is out of range"); VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(index); @@ -60,7 +60,7 @@ namespace Copium vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr); } - void DescriptorSet::AddSamplers(const std::vector& samplers, uint32_t binding) + void DescriptorSet::SetSamplers(const std::vector& samplers, uint32_t binding) { for (size_t i = 0; i < descriptorSets.size(); ++i) { std::vector descriptorWrites{samplers.size()}; diff --git a/CopiumEngine/src/copium/pipeline/DescriptorSet.h b/CopiumEngine/src/copium/pipeline/DescriptorSet.h index 3901315..4f405ac 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorSet.h +++ b/CopiumEngine/src/copium/pipeline/DescriptorSet.h @@ -23,10 +23,10 @@ namespace Copium DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout); ~DescriptorSet(); - void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding); - void AddSampler(const Sampler& sampler, uint32_t binding, int arrayIndex = 0); - void AddSampler(const Sampler& sampler, uint32_t binding, int index, int arrayIndex = 0); - void AddSamplers(const std::vector& sampler, uint32_t binding); + void SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding); + void SetSampler(const Sampler& sampler, uint32_t binding, int arrayIndex = 0); + void SetSampler(const Sampler& sampler, uint32_t binding, int index, int arrayIndex = 0); + void SetSamplers(const std::vector& sampler, uint32_t binding); operator VkDescriptorSet() const; }; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/pipeline/PipelineCreator.cpp b/CopiumEngine/src/copium/pipeline/PipelineCreator.cpp index 5daeb2f..129a434 100644 --- a/CopiumEngine/src/copium/pipeline/PipelineCreator.cpp +++ b/CopiumEngine/src/copium/pipeline/PipelineCreator.cpp @@ -4,40 +4,71 @@ namespace Copium { - PipelineCreator::PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader) - : vertexShader{vertexShader}, - fragmentShader{fragmentShader}, - renderPass{renderPass} - {} + PipelineCreator::PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader) + : vertexShader{vertexShader}, + fragmentShader{fragmentShader}, + renderPass{renderPass} + { + AddShaderDescription(); + } - void PipelineCreator::SetVertexDescriptor(const VertexDescriptor& descriptor) - { - vertexDescriptor = descriptor; - } + void PipelineCreator::SetVertexDescriptor(const VertexDescriptor& descriptor) + { + vertexDescriptor = descriptor; + } - void PipelineCreator::AddDescriptorSetLayoutBinding(uint32_t set, uint32_t binding, VkDescriptorType type, uint32_t count, VkShaderStageFlags stageFlags) - { - CP_ASSERT(set <= descriptorSetLayouts.size(), "AddDescriptorSetLayoutBinding : Cannot add descriptor set with set number greater than the current set count"); - descriptorSetLayouts[set].emplace_back(DescriptorSetBinding{binding, type, count, stageFlags}); - } + void PipelineCreator::SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology) + { + topology = primitiveTopology; + } - void PipelineCreator::SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology) - { - topology = primitiveTopology; - } + void PipelineCreator::SetCullMode(VkCullModeFlags flags) + { + cullMode = flags; + } - void PipelineCreator::SetCullMode(VkCullModeFlags flags) - { - cullMode = flags; - } + void PipelineCreator::SetCullFrontFace(VkFrontFace cullFrontFace) + { + frontFace = cullFrontFace; + } - void PipelineCreator::SetCullFrontFace(VkFrontFace cullFrontFace) - { - frontFace = cullFrontFace; - } + void PipelineCreator::SetDepthTest(bool depthTest) + { + this->depthTest = depthTest; + } - void PipelineCreator::SetDepthTest(bool depthTest) - { - this->depthTest = depthTest; - } + void PipelineCreator::AddShaderDescription() + { + ShaderReflector reflector{vertexShader, fragmentShader}; + for (auto& binding : reflector.bindings) + { + descriptorSetLayouts[binding.set].emplace_back(DescriptorSetBinding{binding.binding, GetDescriptorType(binding.bindingType), binding.arraySize, GetShaderStageFlags(binding.shaderType)}); + } + } + + VkDescriptorType PipelineCreator::GetDescriptorType(BindingType type) + { + switch (type) + { + case BindingType::Sampler2D: + return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + case BindingType::UniformBuffer: + return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + default: + CP_ABORT("GetDescriptorType : Unhandled switch case"); + } + } + + VkShaderStageFlags PipelineCreator::GetShaderStageFlags(ShaderType type) + { + switch (type) + { + case ShaderType::Vertex: + return VK_SHADER_STAGE_VERTEX_BIT; + case ShaderType::Fragment: + return VK_SHADER_STAGE_FRAGMENT_BIT; + default: + CP_ABORT("GetShaderStageFlags : Unhandled switch case"); + } + } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/pipeline/PipelineCreator.h b/CopiumEngine/src/copium/pipeline/PipelineCreator.h index 4e29e1c..3ac20d7 100644 --- a/CopiumEngine/src/copium/pipeline/PipelineCreator.h +++ b/CopiumEngine/src/copium/pipeline/PipelineCreator.h @@ -1,6 +1,7 @@ #pragma once #include "copium/pipeline/VertexDescriptor.h" +#include "copium/util/ShaderReflector.h" #include #include @@ -8,36 +9,39 @@ namespace Copium { - class PipelineCreator - { - struct DescriptorSetBinding - { - uint32_t binding; - VkDescriptorType type; - uint32_t count; - VkShaderStageFlags flags; - }; - friend class Pipeline; - private: - std::map> descriptorSetLayouts{}; + class PipelineCreator + { + struct DescriptorSetBinding + { + uint32_t binding; + VkDescriptorType type; + uint32_t count; + VkShaderStageFlags flags; + }; + friend class Pipeline; + private: + std::map> descriptorSetLayouts{}; - std::string vertexShader; - std::string fragmentShader; - VertexDescriptor vertexDescriptor{}; - VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT; - VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE; - VkRenderPass renderPass = VK_NULL_HANDLE; - bool depthTest = true; + std::string vertexShader; + std::string fragmentShader; + VertexDescriptor vertexDescriptor{}; + VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + VkCullModeFlags cullMode = VK_CULL_MODE_FRONT_BIT; + VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE; + VkRenderPass renderPass = VK_NULL_HANDLE; + bool depthTest = true; - public: - PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader); + public: + PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader); - void SetVertexDescriptor(const VertexDescriptor& descriptor); - void AddDescriptorSetLayoutBinding(uint32_t set, uint32_t binding, VkDescriptorType type, uint32_t count, VkShaderStageFlags stageFlags); - void SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology); - void SetCullMode(VkCullModeFlags flags); - void SetCullFrontFace(VkFrontFace cullFrontFace); - void SetDepthTest(bool depthTest); - }; + void SetVertexDescriptor(const VertexDescriptor& descriptor); + void SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology); + void SetCullMode(VkCullModeFlags flags); + void SetCullFrontFace(VkFrontFace cullFrontFace); + void SetDepthTest(bool depthTest); + private: + void AddShaderDescription(); + static VkDescriptorType GetDescriptorType(BindingType type); + static VkShaderStageFlags GetShaderStageFlags(ShaderType type); + }; } diff --git a/CopiumEngine/src/copium/pipeline/Shader.cpp b/CopiumEngine/src/copium/pipeline/Shader.cpp index be11eb4..a078b51 100644 --- a/CopiumEngine/src/copium/pipeline/Shader.cpp +++ b/CopiumEngine/src/copium/pipeline/Shader.cpp @@ -80,9 +80,8 @@ namespace Copium if (FileSystem::DateModified(filename) < FileSystem::DateModified(spvFilename)) { CP_DEBUG("InitializeShaderModuleFromGlslFile : Loading cached shader file: %s", filename.c_str()); - std::vector data = FileSystem::ReadFile(spvFilename); - CP_ASSERT(data.size() % 4 == 0, "Spv data size is not a factor of 4"); - return InitializeShaderModule((const uint32_t*)data.data(), data.size()); + std::vector data = FileSystem::ReadFile32(spvFilename); + return InitializeShaderModule(data.data(), data.size() * sizeof(uint32_t)); } } } diff --git a/CopiumEngine/src/copium/renderer/DrawCall.cpp b/CopiumEngine/src/copium/renderer/DrawCall.cpp index 3e6ff9f..30048d8 100644 --- a/CopiumEngine/src/copium/renderer/DrawCall.cpp +++ b/CopiumEngine/src/copium/renderer/DrawCall.cpp @@ -10,7 +10,7 @@ namespace Copium vertexBuffer{vulkan, RendererVertex::GetDescriptor(), vertexCount}, descriptorSet{vulkan, descriptorPool, pipeline.GetDescriptorSetLayout(0)} { - descriptorSet.AddSamplers(samplers, 0); + descriptorSet.SetSamplers(samplers, 0); } RendererVertexBuffer& DrawCall::GetVertexBuffer() diff --git a/CopiumEngine/src/copium/renderer/Renderer.cpp b/CopiumEngine/src/copium/renderer/Renderer.cpp index 55b8399..899ff89 100644 --- a/CopiumEngine/src/copium/renderer/Renderer.cpp +++ b/CopiumEngine/src/copium/renderer/Renderer.cpp @@ -25,10 +25,10 @@ namespace Copium void Renderer::Quad(const glm::vec2& from, const glm::vec2& to, const glm::vec3& color) { AllocateQuad(); - AddVertex(from, color, -1, glm::vec2{0, 0}); - AddVertex(glm::vec2{to.x, from.y}, color, -1, glm::vec2{0, 0}); - AddVertex(to, color, -1, glm::vec2{0, 0}); AddVertex(glm::vec2{from.x, to.y}, color, -1, glm::vec2{0, 0}); + AddVertex(to, color, -1, glm::vec2{0, 0}); + AddVertex(glm::vec2{to.x, from.y}, color, -1, glm::vec2{0, 0}); + AddVertex(from, color, -1, glm::vec2{0, 0}); } @@ -36,10 +36,10 @@ namespace Copium { AllocateQuad(); int texIndex = AllocateSampler(sampler); - AddVertex(from, glm::vec3{1,1,1}, texIndex, texCoord1); - AddVertex(glm::vec2{to.x, from.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord2.x, texCoord1.y}); - AddVertex(to, glm::vec3{1,1,1}, texIndex, texCoord2); AddVertex(glm::vec2{from.x, to.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord1.x, texCoord2.y}); + AddVertex(to, glm::vec3{1,1,1}, texIndex, texCoord2); + AddVertex(glm::vec2{to.x, from.y}, glm::vec3{1, 1, 1}, texIndex, glm::vec2{texCoord2.x, texCoord1.y}); + AddVertex(from, glm::vec3{1,1,1}, texIndex, texCoord1); } void Renderer::AddVertex(const glm::vec2& position, const glm::vec3& color, int texindex, const glm::vec2& texCoord) @@ -88,7 +88,6 @@ namespace Copium { PipelineCreator creator{renderPass, "res/shaders/renderer.vert", "res/shaders/renderer.frag"}; creator.SetVertexDescriptor(RendererVertex::GetDescriptor()); - creator.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_NUM_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT); creator.SetDepthTest(false); graphicsPipeline = std::make_unique(vulkan, creator); } @@ -107,7 +106,7 @@ namespace Copium Flush(); NextDrawCall(); } - currentDrawCall->GetDescriptorSet().AddSampler(sampler, 0, vulkan.GetSwapChain().GetFlightIndex(), textureCount); + currentDrawCall->GetDescriptorSet().SetSampler(sampler, 0, vulkan.GetSwapChain().GetFlightIndex(), textureCount); samplers[textureCount] = &sampler; textureCount++; return textureCount - 1; @@ -117,7 +116,6 @@ namespace Copium { if (quadCount + 1 > MAX_NUM_QUADS) { - CP_INFO("Flush"); Flush(); NextDrawCall(); } diff --git a/CopiumEngine/src/copium/util/FileSystem.cpp b/CopiumEngine/src/copium/util/FileSystem.cpp index e1c5fe2..7d3f6fb 100644 --- a/CopiumEngine/src/copium/util/FileSystem.cpp +++ b/CopiumEngine/src/copium/util/FileSystem.cpp @@ -16,6 +16,21 @@ namespace Copium return buffer; } + std::vector FileSystem::ReadFile32(const std::string& filename) + { + std::ifstream file(filename, std::ios::ate | std::ios::binary); + CP_ASSERT(file.is_open(), "ReadFile32 : Failed to open file"); + + size_t fileSize = (size_t)file.tellg(); + CP_ASSERT(fileSize % 4 == 0, "ReadFile32 : byte size is not divisible by 4"); + std::vector buffer(fileSize / 4); + + file.seekg(0); + file.read((char*)buffer.data(), fileSize); + + return buffer; + } + std::string FileSystem::ReadFileStr(const std::string& filename) { std::ifstream file(filename, std::ios::ate | std::ios::binary); diff --git a/CopiumEngine/src/copium/util/FileSystem.h b/CopiumEngine/src/copium/util/FileSystem.h index 7bd5efe..941788c 100644 --- a/CopiumEngine/src/copium/util/FileSystem.h +++ b/CopiumEngine/src/copium/util/FileSystem.h @@ -14,6 +14,7 @@ namespace Copium CP_STATIC_CLASS(FileSystem); public: static std::vector ReadFile(const std::string& filename); + static std::vector ReadFile32(const std::string& filename); static std::string ReadFileStr(const std::string& filename); static void WriteFile(const std::string& filename, const std::string& data); static void WriteFile(const std::string& filename, const char* data, size_t size); diff --git a/CopiumEngine/src/copium/util/ShaderReflector.cpp b/CopiumEngine/src/copium/util/ShaderReflector.cpp new file mode 100644 index 0000000..b6ab41c --- /dev/null +++ b/CopiumEngine/src/copium/util/ShaderReflector.cpp @@ -0,0 +1,125 @@ +#include "copium/util/ShaderReflector.h" + +#include "copium/util/FileSystem.h" + +#include + +namespace Copium +{ + + ShaderReflector::ShaderReflector(const std::string& vertexGlslFile, const std::string& fragmentGlslFile) + { + ParseGlslFile(vertexGlslFile, ShaderType::Vertex); + ParseGlslFile(fragmentGlslFile, ShaderType::Fragment); + } + + void ShaderReflector::ParseGlslFile(const std::string& glslFile, ShaderType shaderType) + { + std::string str = FileSystem::ReadFileStr(glslFile); + int index = 0; + while (index < str.size()) + { + ParseWhitespace(str, index); + if (str[index] == '#') + { + ParseLine(str, index); + continue; + } + if (std::string_view(&str[index], sizeof("layout") - 1) == "layout") + { + ParseLayout(str, index, shaderType); + continue; + } + ParseLine(str, index); + } + } + + void ShaderReflector::ParseLine(const std::string& str, int& index) + { + while(str[index] != '\n' && index < str.size()) index++; + } + + void ShaderReflector::ParseWhitespace(const std::string& str, int& index) + { + while ((str[index] == '\n' || str[index] == ' ' || str[index] == '\t' || str[index] == '\r') && index < str.size()) index++; + } + + void ShaderReflector::ParseLayout(const std::string& str, int& index, ShaderType shaderType) + { + // TODO: Make more robust, currently we might get a crash on the string if the glsl file is invalid + index += sizeof("layout") - 1; + ParseWhitespace(str, index); + index++; // "(" + ParseWhitespace(str, index); + if (std::string_view(&str[index], sizeof("set") - 1) != "set") + { + ParseLine(str, index); + return; + } + ShaderBinding shaderBinding; + shaderBinding.shaderType = shaderType; + index += sizeof("set") - 1; + ParseWhitespace(str, index); + index++; // "=" + ParseWhitespace(str, index); + char* end; + shaderBinding.set = std::strtol(&str[index], &end, 10); + index = end - str.c_str(); + ParseWhitespace(str, index); + index++; // "," + ParseWhitespace(str, index); + index += sizeof("binding") - 1; + ParseWhitespace(str, index); + index++; // "=" + ParseWhitespace(str, index); + shaderBinding.binding = std::strtol(&str[index], &end, 10); + index = end - str.c_str(); + ParseWhitespace(str, index); + index++; // ") + ParseWhitespace(str, index); + index += sizeof("uniform") - 1; + ParseWhitespace(str, index); + + std::string_view type = ParseWord(str, index); + ParseWhitespace(str, index); + if (str[index] == '{') ParseUniformBuffer(str, index); + ParseWhitespace(str, index); + std::string_view name = ParseWord(str, index); + shaderBinding.name = name; + ParseWhitespace(str, index); + + if (str[index] == '[') + { + index++; + shaderBinding.arraySize = std::strtol(&str[index], &end, 10); + } + else + { + shaderBinding.arraySize = 1; + } + + ParseLine(str, index); + if (type == "sampler2D") + shaderBinding.bindingType = BindingType::Sampler2D; + else + shaderBinding.bindingType = BindingType::UniformBuffer; + CP_ASSERT(bindings.emplace(shaderBinding).second, "ParseLayout : multiple layouts with the same binding"); + } + + std::string_view ShaderReflector::ParseWord(const std::string& str, int& index) + { + int start = index; + while (((str[index] >= 'a' && str[index] < 'z') || + (str[index] >= 'A' && str[index] < 'Z') || + (str[index] >= '0' && str[index] <= '9')) || + str[index] == '_' && + index < str.size()) index++; + return std::string_view(&str[start], index - start); + } + + void ShaderReflector::ParseUniformBuffer(const std::string& str, int& index) + { + while (str[index] != '}' && index < str.size()) index++; + if (index < str.size()) index++; // go past "}" + } +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/util/ShaderReflector.h b/CopiumEngine/src/copium/util/ShaderReflector.h new file mode 100644 index 0000000..358e053 --- /dev/null +++ b/CopiumEngine/src/copium/util/ShaderReflector.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +namespace Copium +{ + enum class BindingType + { + Sampler2D, UniformBuffer + }; + + enum class ShaderType + { + Vertex, Fragment + }; + + struct ShaderBinding + { + std::string name; + uint32_t set; + uint32_t binding; + uint32_t arraySize; + BindingType bindingType; + ShaderType shaderType; + + bool operator<(const ShaderBinding& rhs) const + { + if (set != rhs.set) + return set < rhs.set; + if (binding != rhs.binding) + return binding < rhs.binding; + } + }; + + class ShaderReflector + { + public: + std::set bindings; + public: + ShaderReflector(const std::string& vertexGlslFile, const std::string& fragmentGlslFile); + + private: + void ParseGlslFile(const std::string& glslFile, ShaderType type); + void ParseLine(const std::string& str, int& index); + void ParseWhitespace(const std::string& str, int& index); + void ParseLayout(const std::string& str, int& index, ShaderType type); + std::string_view ParseWord(const std::string& str, int& index); + void ParseUniformBuffer(const std::string& str, int& index); + }; +}