diff --git a/shaders/colored_triangle.slang b/shaders/colored_triangle.slang deleted file mode 100644 index d61c968..0000000 --- a/shaders/colored_triangle.slang +++ /dev/null @@ -1,30 +0,0 @@ -static float2 positions[3] = float2[]( - float2(0.0, -0.5), - float2(0.5, 0.5), - float2(-0.5, 0.5) -); - -static float3 colors[3] = float3[] ( - float3(1.0, 0.0, 0.0), - float3(0.0, 1.0, 0.0), - float3(0.0, 0.0, 1.0) -); - -struct VertexOutput { - float3 color; - float4 sv_position : SV_Position; -}; - -[shader("vertex")] -VertexOutput vertMain(uint vid : SV_VertexID) { - VertexOutput output; - output.sv_position = float4(positions[vid], 0.0, 1.0); - output.color = colors[vid]; - return output; -} - -[shader("fragment")] -float4 fragMain(VertexOutput inVert) : SV_Target { - float3 color = inVert.color; - return float4(color, 1.0); -} diff --git a/shaders/colored_triangle_fragment.frag b/shaders/colored_triangle_fragment.frag new file mode 100644 index 0000000..d67c317 --- /dev/null +++ b/shaders/colored_triangle_fragment.frag @@ -0,0 +1,13 @@ +#version 450 + +//shader input +layout (location = 0) in vec3 inColor; + +//output write +layout (location = 0) out vec4 outFragColor; + +void main() +{ + //return red + outFragColor = vec4(inColor,1.0f); +} diff --git a/shaders/colored_triangle_vertices.vert b/shaders/colored_triangle_vertices.vert new file mode 100644 index 0000000..fe0408e --- /dev/null +++ b/shaders/colored_triangle_vertices.vert @@ -0,0 +1,24 @@ +#version 450 + +layout (location = 0) out vec3 outColor; + +void main() +{ + //const array of positions for the triangle + const vec3 positions[3] = vec3[3]( + vec3(1.f,1.f, 0.0f), + vec3(-1.f,1.f, 0.0f), + vec3(0.f,-1.f, 0.0f) + ); + + //const array of colors for the triangle + const vec3 colors[3] = vec3[3]( + vec3(1.0f, 0.0f, 0.0f), //red + vec3(0.0f, 1.0f, 0.0f), //green + vec3(00.f, 0.0f, 1.0f) //blue + ); + + //output the position of each vertex + gl_Position = vec4(positions[gl_VertexIndex], 1.0f); + outColor = colors[gl_VertexIndex]; +} diff --git a/src/Engine/engine/engine.h b/src/Engine/engine/engine.h index d58986e..d5193b0 100644 --- a/src/Engine/engine/engine.h +++ b/src/Engine/engine/engine.h @@ -840,6 +840,7 @@ void Engine::initPipelines() { fmt::println("[Engine:Init] Initializing pipelines..."); #endif initBackgroundPipelines(); + initTrianglePipeline(); #ifdef DEBUG fmt::println("[Engine:Init] Pipelines initialized !"); @@ -1000,6 +1001,87 @@ void Engine::initBackgroundPipelines() { #endif } +void Engine::initTrianglePipeline() { + #ifdef DEBUG + fmt::println("[Engine:Init] Initializing triangle pipeline..."); + #endif + // Create the shader + VkShaderModule triangleFragShader; + if(!vkutil::loadShaderModule("shaders/colored_triangle_fragment.spv", _device, &triangleFragShader)) { + fmt::println("[Engine:Error] Failed to load the triangle fragment shader !"); + } else { + fmt::println("[Engine:Info] Successfully loaded the triangle fragment shader !"); + } + + VkShaderModule triangleVertShader; + if(!vkutil::loadShaderModule("shaders/colored_triangle_vertices.spv", _device, &triangleVertShader)) { + fmt::println("[Engine:Error] Failed to load the triangle vertex shader !"); + } else { + fmt::println("[Engine:Info] Successfully loaded the triangle vertex shader !"); + } + + // Build the pipeline with the helper functions + // Build the pipeline layout that controls the inputs/outputs of the shader + // We are not using descriptor sets or other systems yet, so no need to use anything other than empty default + // This is because we don't have push constants or descriptor bindings + VkPipelineLayoutCreateInfo pipelineLayoutInfo = vkinit::pipelineLayoutCreateInfo(); + VK_CHECK( + vkCreatePipelineLayout( + _device, + &pipelineLayoutInfo, + nullptr, + &_trianglePipelineLayout + ) + ); + + PipelineBuilder pipelineBuilder; + pipelineBuilder._pipelineLayout = _trianglePipelineLayout; + // Connect both the vertex and fragment shader together + // Todo : Handle the case where they are both in the same VkShaderModule, + // with slang shaders for example + pipelineBuilder.setShaders(triangleVertShader, triangleFragShader); + // Draw triangles + // Can also draw "wireframe" + pipelineBuilder.setInputTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + // Fill those triangles. + // For wireframe, don't + pipelineBuilder.setPolygonMode(VK_POLYGON_MODE_FILL); + // No backface culling atm + // Enable it for optimization, but beware of clockwise/anticlockwise coordinates + // Also, Vulkan uses -Y, so take note + pipelineBuilder.setCullMode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE); + // No multisampling, + // used for a more "retro" look, + // and more performance + // also useless because it's a single triangle + pipelineBuilder.setMultisamplingNone(); + // No blending + pipelineBuilder.disableBlending(); + // No depth testing, + // 'cause no depth buffer nor 3D triangle + pipelineBuilder.disableDepthtest(); + + // Connect the image format we will draw into, from draw image + pipelineBuilder.setColorAttachmentFormat(_drawImage.imageFormat); + pipelineBuilder.setDepthFormat(VK_FORMAT_UNDEFINED); + + // Finally build the pipeline + _trianglePipeline = pipelineBuilder.buildPipeline(_device); + + // clean structures + vkDestroyShaderModule(_device, triangleFragShader, nullptr); + vkDestroyShaderModule(_device, triangleVertShader, nullptr); + + _mainDeletionQueue.pushFunction([this]() { + vkDestroyPipelineLayout(_device, _trianglePipelineLayout, nullptr); + vkDestroyPipeline(_device, _trianglePipeline, nullptr); + }); + + #ifdef DEBUG + fmt::println("[Engine:Init] Triangle pipeline initalized !"); + #endif +} + void Engine::initImgui() { #ifdef DEBUG fmt::println("[Engine:Init] Initializing ImGui..."); diff --git a/src/Engine/engine/initializers.h b/src/Engine/engine/initializers.h index e0ea423..e9462cb 100644 --- a/src/Engine/engine/initializers.h +++ b/src/Engine/engine/initializers.h @@ -70,6 +70,8 @@ namespace vkinit { VkRenderingAttachmentInfo* depthAttachment ); + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(); + VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo( VkShaderStageFlagBits stage, VkShaderModule shaderModule, @@ -310,6 +312,21 @@ namespace vkinit { return renderInfo; } + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo() { + VkPipelineLayoutCreateInfo info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + // Empty defaults + .flags = 0, + .setLayoutCount = 0, + .pSetLayouts = nullptr, + .pushConstantRangeCount = 0, + .pPushConstantRanges = nullptr, + }; + + return info; + } + VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo( VkShaderStageFlagBits stage, VkShaderModule shaderModule, diff --git a/src/Engine/engine/pipelines.h b/src/Engine/engine/pipelines.h index d9d8c69..e588075 100644 --- a/src/Engine/engine/pipelines.h +++ b/src/Engine/engine/pipelines.h @@ -28,6 +28,7 @@ class PipelineBuilder { VkPipelineLayout _pipelineLayout; VkPipelineDepthStencilStateCreateInfo _depthStencil; VkPipelineRenderingCreateInfo _renderInfo; + VkFormat _colorAttachmentFormat; PipelineBuilder() { clear(); } @@ -330,6 +331,15 @@ void PipelineBuilder::disableBlending() { _colorBlendAttachment.blendEnable = VK_FALSE; } +void PipelineBuilder::setColorAttachmentFormat( + VkFormat format +) { + _colorAttachmentFormat = format; + // connect the format to the renderInfo structure + _renderInfo.colorAttachmentCount = 1; + _renderInfo.pColorAttachmentFormats = &_colorAttachmentFormat; +} + void PipelineBuilder::setDepthFormat( VkFormat format ) { diff --git a/src/imgui b/src/imgui index 5220a3f..b48d1af 160000 --- a/src/imgui +++ b/src/imgui @@ -1 +1 @@ -Subproject commit 5220a3f48d39c000da8b46fb0fccf3dd62695c51 +Subproject commit b48d1afbe8ee8b238e2961dc363a949dd7304e23