Add ShaderReflector
- Used to look at the shader files and find set/binding automatically
This commit is contained in:
@@ -194,6 +194,7 @@
|
|||||||
<ClCompile Include="src\copium\pipeline\Shader.cpp" />
|
<ClCompile Include="src\copium\pipeline\Shader.cpp" />
|
||||||
<ClCompile Include="src\copium\core\SwapChain.cpp" />
|
<ClCompile Include="src\copium\core\SwapChain.cpp" />
|
||||||
<ClCompile Include="src\copium\sampler\Texture2D.cpp" />
|
<ClCompile Include="src\copium\sampler\Texture2D.cpp" />
|
||||||
|
<ClCompile Include="src\copium\util\ShaderReflector.cpp" />
|
||||||
<ClCompile Include="src\copium\util\Timer.cpp" />
|
<ClCompile Include="src\copium\util\Timer.cpp" />
|
||||||
<ClCompile Include="src\copium\buffer\UniformBuffer.cpp" />
|
<ClCompile Include="src\copium\buffer\UniformBuffer.cpp" />
|
||||||
<ClCompile Include="src\copium\mesh\Vertex.cpp" />
|
<ClCompile Include="src\copium\mesh\Vertex.cpp" />
|
||||||
@@ -233,6 +234,7 @@
|
|||||||
<ClInclude Include="src\copium\core\Instance.h" />
|
<ClInclude Include="src\copium\core\Instance.h" />
|
||||||
<ClInclude Include="src\copium\core\QueueFamilies.h" />
|
<ClInclude Include="src\copium\core\QueueFamilies.h" />
|
||||||
<ClInclude Include="src\copium\core\SwapChain.h" />
|
<ClInclude Include="src\copium\core\SwapChain.h" />
|
||||||
|
<ClInclude Include="src\copium\util\ShaderReflector.h" />
|
||||||
<ClInclude Include="src\copium\util\Timer.h" />
|
<ClInclude Include="src\copium\util\Timer.h" />
|
||||||
<ClInclude Include="src\copium\mesh\Vertex.h" />
|
<ClInclude Include="src\copium\mesh\Vertex.h" />
|
||||||
<ClInclude Include="src\copium\buffer\VertexBuffer.h" />
|
<ClInclude Include="src\copium\buffer\VertexBuffer.h" />
|
||||||
|
|||||||
@@ -123,6 +123,9 @@
|
|||||||
<ClCompile Include="src\copium\renderer\DrawCall.cpp">
|
<ClCompile Include="src\copium\renderer\DrawCall.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\copium\util\ShaderReflector.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\copium\sampler\DepthAttachment.h">
|
<ClInclude Include="src\copium\sampler\DepthAttachment.h">
|
||||||
@@ -236,6 +239,9 @@
|
|||||||
<ClInclude Include="src\copium\renderer\DrawCall.h">
|
<ClInclude Include="src\copium\renderer\DrawCall.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\copium\util\ShaderReflector.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="res\shaders\shader.frag" />
|
<None Include="res\shaders\shader.frag" />
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler2D texSampler;
|
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;
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outColor = texture(texSampler, fragTexCoord);
|
outColor = texture(texSampler, inTexCoord);
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
layout(location = 0) in vec2 inPosition;
|
layout(location = 0) in vec2 inPosition;
|
||||||
|
|
||||||
layout(location = 0) out vec2 fragTexCoord;
|
layout(location = 0) out vec2 outTexCoord;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(inPosition * 0.5, 0.999, 1.0);
|
gl_Position = vec4(inPosition * 0.5, 0.999, 1.0);
|
||||||
fragTexCoord = inPosition * 0.5 + 0.5;
|
outTexCoord = inPosition * 0.5 + 0.5;
|
||||||
}
|
}
|
||||||
@@ -2,51 +2,51 @@
|
|||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler2D texSamplers[32];
|
layout(set = 0, binding = 0) uniform sampler2D texSamplers[32];
|
||||||
|
|
||||||
layout(location = 0) in vec3 fragColor;
|
layout(location = 0) in vec3 inColor;
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 inTexCoord;
|
||||||
layout(location = 2) in flat int fragTexIndex;
|
layout(location = 2) in flat int inTexIndex;
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
vec4 TextureColor()
|
vec4 TextureColor()
|
||||||
{
|
{
|
||||||
if(fragTexIndex == 0) return texture(texSamplers[0], fragTexCoord);
|
if(inTexIndex == 0) return texture(texSamplers[0], inTexCoord);
|
||||||
if(fragTexIndex == 1) return texture(texSamplers[1], fragTexCoord);
|
if(inTexIndex == 1) return texture(texSamplers[1], inTexCoord);
|
||||||
if(fragTexIndex == 2) return texture(texSamplers[2], fragTexCoord);
|
if(inTexIndex == 2) return texture(texSamplers[2], inTexCoord);
|
||||||
if(fragTexIndex == 3) return texture(texSamplers[3], fragTexCoord);
|
if(inTexIndex == 3) return texture(texSamplers[3], inTexCoord);
|
||||||
if(fragTexIndex == 4) return texture(texSamplers[4], fragTexCoord);
|
if(inTexIndex == 4) return texture(texSamplers[4], inTexCoord);
|
||||||
if(fragTexIndex == 5) return texture(texSamplers[5], fragTexCoord);
|
if(inTexIndex == 5) return texture(texSamplers[5], inTexCoord);
|
||||||
if(fragTexIndex == 6) return texture(texSamplers[6], fragTexCoord);
|
if(inTexIndex == 6) return texture(texSamplers[6], inTexCoord);
|
||||||
if(fragTexIndex == 7) return texture(texSamplers[7], fragTexCoord);
|
if(inTexIndex == 7) return texture(texSamplers[7], inTexCoord);
|
||||||
if(fragTexIndex == 8) return texture(texSamplers[8], fragTexCoord);
|
if(inTexIndex == 8) return texture(texSamplers[8], inTexCoord);
|
||||||
if(fragTexIndex == 9) return texture(texSamplers[9], fragTexCoord);
|
if(inTexIndex == 9) return texture(texSamplers[9], inTexCoord);
|
||||||
if(fragTexIndex == 10) return texture(texSamplers[10], fragTexCoord);
|
if(inTexIndex == 10) return texture(texSamplers[10], inTexCoord);
|
||||||
if(fragTexIndex == 11) return texture(texSamplers[11], fragTexCoord);
|
if(inTexIndex == 11) return texture(texSamplers[11], inTexCoord);
|
||||||
if(fragTexIndex == 12) return texture(texSamplers[12], fragTexCoord);
|
if(inTexIndex == 12) return texture(texSamplers[12], inTexCoord);
|
||||||
if(fragTexIndex == 13) return texture(texSamplers[13], fragTexCoord);
|
if(inTexIndex == 13) return texture(texSamplers[13], inTexCoord);
|
||||||
if(fragTexIndex == 14) return texture(texSamplers[14], fragTexCoord);
|
if(inTexIndex == 14) return texture(texSamplers[14], inTexCoord);
|
||||||
if(fragTexIndex == 15) return texture(texSamplers[15], fragTexCoord);
|
if(inTexIndex == 15) return texture(texSamplers[15], inTexCoord);
|
||||||
if(fragTexIndex == 16) return texture(texSamplers[16], fragTexCoord);
|
if(inTexIndex == 16) return texture(texSamplers[16], inTexCoord);
|
||||||
if(fragTexIndex == 17) return texture(texSamplers[17], fragTexCoord);
|
if(inTexIndex == 17) return texture(texSamplers[17], inTexCoord);
|
||||||
if(fragTexIndex == 18) return texture(texSamplers[18], fragTexCoord);
|
if(inTexIndex == 18) return texture(texSamplers[18], inTexCoord);
|
||||||
if(fragTexIndex == 19) return texture(texSamplers[19], fragTexCoord);
|
if(inTexIndex == 19) return texture(texSamplers[19], inTexCoord);
|
||||||
if(fragTexIndex == 20) return texture(texSamplers[20], fragTexCoord);
|
if(inTexIndex == 20) return texture(texSamplers[20], inTexCoord);
|
||||||
if(fragTexIndex == 21) return texture(texSamplers[21], fragTexCoord);
|
if(inTexIndex == 21) return texture(texSamplers[21], inTexCoord);
|
||||||
if(fragTexIndex == 22) return texture(texSamplers[22], fragTexCoord);
|
if(inTexIndex == 22) return texture(texSamplers[22], inTexCoord);
|
||||||
if(fragTexIndex == 23) return texture(texSamplers[23], fragTexCoord);
|
if(inTexIndex == 23) return texture(texSamplers[23], inTexCoord);
|
||||||
if(fragTexIndex == 24) return texture(texSamplers[24], fragTexCoord);
|
if(inTexIndex == 24) return texture(texSamplers[24], inTexCoord);
|
||||||
if(fragTexIndex == 25) return texture(texSamplers[25], fragTexCoord);
|
if(inTexIndex == 25) return texture(texSamplers[25], inTexCoord);
|
||||||
if(fragTexIndex == 26) return texture(texSamplers[26], fragTexCoord);
|
if(inTexIndex == 26) return texture(texSamplers[26], inTexCoord);
|
||||||
if(fragTexIndex == 27) return texture(texSamplers[27], fragTexCoord);
|
if(inTexIndex == 27) return texture(texSamplers[27], inTexCoord);
|
||||||
if(fragTexIndex == 28) return texture(texSamplers[28], fragTexCoord);
|
if(inTexIndex == 28) return texture(texSamplers[28], inTexCoord);
|
||||||
if(fragTexIndex == 29) return texture(texSamplers[29], fragTexCoord);
|
if(inTexIndex == 29) return texture(texSamplers[29], inTexCoord);
|
||||||
if(fragTexIndex == 30) return texture(texSamplers[30], fragTexCoord);
|
if(inTexIndex == 30) return texture(texSamplers[30], inTexCoord);
|
||||||
if(fragTexIndex == 31) return texture(texSamplers[31], fragTexCoord);
|
if(inTexIndex == 31) return texture(texSamplers[31], inTexCoord);
|
||||||
return vec4(1, 1, 1, 1);
|
return vec4(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main()
|
||||||
outColor = vec4(fragColor, 1.0) * TextureColor();
|
{
|
||||||
// outColor = vec4(fragTexCoord, 0.0, 1.0);
|
outColor = vec4(inColor, 1.0) * TextureColor();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ layout(location = 0) out vec3 fragColor;
|
|||||||
layout(location = 1) out vec2 fragTexCoord;
|
layout(location = 1) out vec2 fragTexCoord;
|
||||||
layout(location = 2) out int fragTexIndex;
|
layout(location = 2) out int fragTexIndex;
|
||||||
|
|
||||||
void main() {
|
void main()
|
||||||
|
{
|
||||||
gl_Position = vec4(inPosition, 1.0);
|
gl_Position = vec4(inPosition, 1.0);
|
||||||
fragColor = inColor;
|
fragColor = inColor;
|
||||||
fragTexCoord = inTexCoord;
|
fragTexCoord = inTexCoord;
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
layout(set = 0, binding = 1) uniform sampler2D texSampler;
|
layout(set = 0, binding = 1) uniform sampler2D texSampler;
|
||||||
|
|
||||||
layout(location = 0) in vec3 fragColor;
|
layout(location = 0) in vec3 inColor;
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 inTexCoord;
|
||||||
layout(location = 2) in vec3 fragPosition;
|
layout(location = 2) in vec3 inPosition;
|
||||||
layout(location = 3) in vec3 fragLightPos;
|
layout(location = 3) in vec3 inLightPos;
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
void main() {
|
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;
|
float scale = 0.45 + max(dot(vec3(0, 1, 0), normalize(inLightPos - inPosition)), 0.0);
|
||||||
|
outColor = vec4(inColor, 1.0) * texture(texSampler, inTexCoord) * scale;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,16 @@ layout(location = 0) in vec3 inPosition;
|
|||||||
layout(location = 1) in vec3 inColor;
|
layout(location = 1) in vec3 inColor;
|
||||||
layout(location = 2) in vec2 inTexCoord;
|
layout(location = 2) in vec2 inTexCoord;
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragColor;
|
layout(location = 0) out vec3 outColor;
|
||||||
layout(location = 1) out vec2 fragTexCoord;
|
layout(location = 1) out vec2 outTexCoord;
|
||||||
layout(location = 2) out vec3 fragPosition;
|
layout(location = 2) out vec3 outPosition;
|
||||||
layout(location = 3) out vec3 fragLightPos;
|
layout(location = 3) out vec3 outLightPos;
|
||||||
|
|
||||||
void main() {
|
void main()
|
||||||
|
{
|
||||||
gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
||||||
fragColor = inColor;
|
outColor = inColor;
|
||||||
fragTexCoord = inTexCoord;
|
outTexCoord = inTexCoord;
|
||||||
fragPosition = vec3(ubo.model * vec4(inPosition, 1.0));
|
outPosition = vec3(ubo.model * vec4(inPosition, 1.0));
|
||||||
fragLightPos = ubo.lightPos;
|
outLightPos = ubo.lightPos;
|
||||||
}
|
}
|
||||||
@@ -29,9 +29,9 @@ namespace Copium
|
|||||||
|
|
||||||
const std::vector<VertexPassthrough> verticesPassthrough = {
|
const std::vector<VertexPassthrough> 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}},
|
||||||
|
VertexPassthrough{{ 1.0f, 1.0f}},
|
||||||
|
VertexPassthrough{{ 1.0f, -1.0f}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<uint16_t> indicesPassthrough = {
|
const std::vector<uint16_t> indicesPassthrough = {
|
||||||
@@ -69,7 +69,7 @@ namespace Copium
|
|||||||
if (framebuffer->GetWidth() != vulkan->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != vulkan->GetSwapChain().GetExtent().height)
|
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);
|
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())
|
if (!vulkan->GetSwapChain().BeginPresent())
|
||||||
@@ -113,26 +113,21 @@ namespace Copium
|
|||||||
descriptorPool = std::make_unique<DescriptorPool>(*vulkan);
|
descriptorPool = std::make_unique<DescriptorPool>(*vulkan);
|
||||||
|
|
||||||
descriptorSet = std::make_unique<DescriptorSet>(*vulkan, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
|
descriptorSet = std::make_unique<DescriptorSet>(*vulkan, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
|
||||||
descriptorSet->AddUniform(*shaderUniformBuffer, 0);
|
descriptorSet->SetUniformBuffer(*shaderUniformBuffer, 0);
|
||||||
descriptorSet->AddSampler(*texture2D, 1);
|
descriptorSet->SetSampler(*texture2D, 1);
|
||||||
|
|
||||||
descriptorSetPassthrough = std::make_unique<DescriptorSet>(*vulkan, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
|
descriptorSetPassthrough = std::make_unique<DescriptorSet>(*vulkan, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
|
||||||
descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
|
descriptorSetPassthrough->SetSampler(framebuffer->GetColorAttachment(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeGraphicsPipeline()
|
void Application::InitializeGraphicsPipeline()
|
||||||
{
|
{
|
||||||
PipelineCreator creator{framebuffer->GetRenderPass(), "res/shaders/shader.vert", "res/shaders/shader.frag"};
|
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.SetVertexDescriptor(Vertex::GetDescriptor());
|
||||||
creator.SetCullMode(VK_CULL_MODE_NONE);
|
|
||||||
graphicsPipeline = std::make_unique<Pipeline>(*vulkan, creator);
|
graphicsPipeline = std::make_unique<Pipeline>(*vulkan, creator);
|
||||||
|
|
||||||
PipelineCreator creatorPassthrough{vulkan->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"};
|
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.SetVertexDescriptor(VertexPassthrough::GetDescriptor());
|
||||||
creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE);
|
|
||||||
graphicsPipelinePassthrough = std::make_unique<Pipeline>(*vulkan, creatorPassthrough);
|
graphicsPipelinePassthrough = std::make_unique<Pipeline>(*vulkan, creatorPassthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Copium
|
|||||||
descriptorPool.FreeDescriptorSets(descriptorSets);
|
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) {
|
for (size_t i = 0; i < descriptorSets.size(); ++i) {
|
||||||
VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(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)
|
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");
|
CP_ASSERT(index >= 0 && index < descriptorSets.size(), "AddSampler : index is out of range");
|
||||||
VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(index);
|
VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(index);
|
||||||
@@ -60,7 +60,7 @@ namespace Copium
|
|||||||
vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr);
|
vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::AddSamplers(const std::vector<const Sampler*>& samplers, uint32_t binding)
|
void DescriptorSet::SetSamplers(const std::vector<const Sampler*>& samplers, uint32_t binding)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < descriptorSets.size(); ++i) {
|
for (size_t i = 0; i < descriptorSets.size(); ++i) {
|
||||||
std::vector<VkWriteDescriptorSet> descriptorWrites{samplers.size()};
|
std::vector<VkWriteDescriptorSet> descriptorWrites{samplers.size()};
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ namespace Copium
|
|||||||
DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout);
|
DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout);
|
||||||
~DescriptorSet();
|
~DescriptorSet();
|
||||||
|
|
||||||
void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding);
|
void SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding);
|
||||||
void AddSampler(const Sampler& sampler, uint32_t binding, int arrayIndex = 0);
|
void SetSampler(const Sampler& sampler, uint32_t binding, int arrayIndex = 0);
|
||||||
void AddSampler(const Sampler& sampler, uint32_t binding, int index, int arrayIndex = 0);
|
void SetSampler(const Sampler& sampler, uint32_t binding, int index, int arrayIndex = 0);
|
||||||
void AddSamplers(const std::vector<const Sampler*>& sampler, uint32_t binding);
|
void SetSamplers(const std::vector<const Sampler*>& sampler, uint32_t binding);
|
||||||
operator VkDescriptorSet() const;
|
operator VkDescriptorSet() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -4,40 +4,71 @@
|
|||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
PipelineCreator::PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader)
|
PipelineCreator::PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader)
|
||||||
: vertexShader{vertexShader},
|
: vertexShader{vertexShader},
|
||||||
fragmentShader{fragmentShader},
|
fragmentShader{fragmentShader},
|
||||||
renderPass{renderPass}
|
renderPass{renderPass}
|
||||||
{}
|
{
|
||||||
|
AddShaderDescription();
|
||||||
|
}
|
||||||
|
|
||||||
void PipelineCreator::SetVertexDescriptor(const VertexDescriptor& descriptor)
|
void PipelineCreator::SetVertexDescriptor(const VertexDescriptor& descriptor)
|
||||||
{
|
{
|
||||||
vertexDescriptor = descriptor;
|
vertexDescriptor = descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCreator::AddDescriptorSetLayoutBinding(uint32_t set, uint32_t binding, VkDescriptorType type, uint32_t count, VkShaderStageFlags stageFlags)
|
void PipelineCreator::SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology)
|
||||||
{
|
{
|
||||||
CP_ASSERT(set <= descriptorSetLayouts.size(), "AddDescriptorSetLayoutBinding : Cannot add descriptor set with set number greater than the current set count");
|
topology = primitiveTopology;
|
||||||
descriptorSetLayouts[set].emplace_back(DescriptorSetBinding{binding, type, count, stageFlags});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineCreator::SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology)
|
void PipelineCreator::SetCullMode(VkCullModeFlags flags)
|
||||||
{
|
{
|
||||||
topology = primitiveTopology;
|
cullMode = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCreator::SetCullMode(VkCullModeFlags flags)
|
void PipelineCreator::SetCullFrontFace(VkFrontFace cullFrontFace)
|
||||||
{
|
{
|
||||||
cullMode = flags;
|
frontFace = cullFrontFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCreator::SetCullFrontFace(VkFrontFace cullFrontFace)
|
void PipelineCreator::SetDepthTest(bool depthTest)
|
||||||
{
|
{
|
||||||
frontFace = cullFrontFace;
|
this->depthTest = depthTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCreator::SetDepthTest(bool depthTest)
|
void PipelineCreator::AddShaderDescription()
|
||||||
{
|
{
|
||||||
this->depthTest = depthTest;
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/pipeline/VertexDescriptor.h"
|
#include "copium/pipeline/VertexDescriptor.h"
|
||||||
|
#include "copium/util/ShaderReflector.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -8,36 +9,39 @@
|
|||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
class PipelineCreator
|
class PipelineCreator
|
||||||
{
|
{
|
||||||
struct DescriptorSetBinding
|
struct DescriptorSetBinding
|
||||||
{
|
{
|
||||||
uint32_t binding;
|
uint32_t binding;
|
||||||
VkDescriptorType type;
|
VkDescriptorType type;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
VkShaderStageFlags flags;
|
VkShaderStageFlags flags;
|
||||||
};
|
};
|
||||||
friend class Pipeline;
|
friend class Pipeline;
|
||||||
private:
|
private:
|
||||||
std::map<uint32_t, std::vector<DescriptorSetBinding>> descriptorSetLayouts{};
|
std::map<uint32_t, std::vector<DescriptorSetBinding>> descriptorSetLayouts{};
|
||||||
|
|
||||||
std::string vertexShader;
|
std::string vertexShader;
|
||||||
std::string fragmentShader;
|
std::string fragmentShader;
|
||||||
VertexDescriptor vertexDescriptor{};
|
VertexDescriptor vertexDescriptor{};
|
||||||
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
|
VkCullModeFlags cullMode = VK_CULL_MODE_FRONT_BIT;
|
||||||
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||||
bool depthTest = true;
|
bool depthTest = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader);
|
PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader);
|
||||||
|
|
||||||
void SetVertexDescriptor(const VertexDescriptor& descriptor);
|
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 SetPrimitiveTopology(VkPrimitiveTopology primitiveTopology);
|
void SetCullMode(VkCullModeFlags flags);
|
||||||
void SetCullMode(VkCullModeFlags flags);
|
void SetCullFrontFace(VkFrontFace cullFrontFace);
|
||||||
void SetCullFrontFace(VkFrontFace cullFrontFace);
|
void SetDepthTest(bool depthTest);
|
||||||
void SetDepthTest(bool depthTest);
|
private:
|
||||||
};
|
void AddShaderDescription();
|
||||||
|
static VkDescriptorType GetDescriptorType(BindingType type);
|
||||||
|
static VkShaderStageFlags GetShaderStageFlags(ShaderType type);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,9 +80,8 @@ namespace Copium
|
|||||||
if (FileSystem::DateModified(filename) < FileSystem::DateModified(spvFilename))
|
if (FileSystem::DateModified(filename) < FileSystem::DateModified(spvFilename))
|
||||||
{
|
{
|
||||||
CP_DEBUG("InitializeShaderModuleFromGlslFile : Loading cached shader file: %s", filename.c_str());
|
CP_DEBUG("InitializeShaderModuleFromGlslFile : Loading cached shader file: %s", filename.c_str());
|
||||||
std::vector<char> data = FileSystem::ReadFile(spvFilename);
|
std::vector<uint32_t> data = FileSystem::ReadFile32(spvFilename);
|
||||||
CP_ASSERT(data.size() % 4 == 0, "Spv data size is not a factor of 4");
|
return InitializeShaderModule(data.data(), data.size() * sizeof(uint32_t));
|
||||||
return InitializeShaderModule((const uint32_t*)data.data(), data.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Copium
|
|||||||
vertexBuffer{vulkan, RendererVertex::GetDescriptor(), vertexCount},
|
vertexBuffer{vulkan, RendererVertex::GetDescriptor(), vertexCount},
|
||||||
descriptorSet{vulkan, descriptorPool, pipeline.GetDescriptorSetLayout(0)}
|
descriptorSet{vulkan, descriptorPool, pipeline.GetDescriptorSetLayout(0)}
|
||||||
{
|
{
|
||||||
descriptorSet.AddSamplers(samplers, 0);
|
descriptorSet.SetSamplers(samplers, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererVertexBuffer& DrawCall::GetVertexBuffer()
|
RendererVertexBuffer& DrawCall::GetVertexBuffer()
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ namespace Copium
|
|||||||
void Renderer::Quad(const glm::vec2& from, const glm::vec2& to, const glm::vec3& color)
|
void Renderer::Quad(const glm::vec2& from, const glm::vec2& to, const glm::vec3& color)
|
||||||
{
|
{
|
||||||
AllocateQuad();
|
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(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();
|
AllocateQuad();
|
||||||
int texIndex = AllocateSampler(sampler);
|
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(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)
|
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"};
|
PipelineCreator creator{renderPass, "res/shaders/renderer.vert", "res/shaders/renderer.frag"};
|
||||||
creator.SetVertexDescriptor(RendererVertex::GetDescriptor());
|
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);
|
creator.SetDepthTest(false);
|
||||||
graphicsPipeline = std::make_unique<Pipeline>(vulkan, creator);
|
graphicsPipeline = std::make_unique<Pipeline>(vulkan, creator);
|
||||||
}
|
}
|
||||||
@@ -107,7 +106,7 @@ namespace Copium
|
|||||||
Flush();
|
Flush();
|
||||||
NextDrawCall();
|
NextDrawCall();
|
||||||
}
|
}
|
||||||
currentDrawCall->GetDescriptorSet().AddSampler(sampler, 0, vulkan.GetSwapChain().GetFlightIndex(), textureCount);
|
currentDrawCall->GetDescriptorSet().SetSampler(sampler, 0, vulkan.GetSwapChain().GetFlightIndex(), textureCount);
|
||||||
samplers[textureCount] = &sampler;
|
samplers[textureCount] = &sampler;
|
||||||
textureCount++;
|
textureCount++;
|
||||||
return textureCount - 1;
|
return textureCount - 1;
|
||||||
@@ -117,7 +116,6 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
if (quadCount + 1 > MAX_NUM_QUADS)
|
if (quadCount + 1 > MAX_NUM_QUADS)
|
||||||
{
|
{
|
||||||
CP_INFO("Flush");
|
|
||||||
Flush();
|
Flush();
|
||||||
NextDrawCall();
|
NextDrawCall();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,21 @@ namespace Copium
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> 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<uint32_t> buffer(fileSize / 4);
|
||||||
|
|
||||||
|
file.seekg(0);
|
||||||
|
file.read((char*)buffer.data(), fileSize);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
std::string FileSystem::ReadFileStr(const std::string& filename)
|
std::string FileSystem::ReadFileStr(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Copium
|
|||||||
CP_STATIC_CLASS(FileSystem);
|
CP_STATIC_CLASS(FileSystem);
|
||||||
public:
|
public:
|
||||||
static std::vector<char> ReadFile(const std::string& filename);
|
static std::vector<char> ReadFile(const std::string& filename);
|
||||||
|
static std::vector<uint32_t> ReadFile32(const std::string& filename);
|
||||||
static std::string ReadFileStr(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 std::string& data);
|
||||||
static void WriteFile(const std::string& filename, const char* data, size_t size);
|
static void WriteFile(const std::string& filename, const char* data, size_t size);
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
#include "copium/util/ShaderReflector.h"
|
||||||
|
|
||||||
|
#include "copium/util/FileSystem.h"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
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 "}"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
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<ShaderBinding> 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);
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user