My Journey Of Building Graphics Rendering Engine Using Vulkan SDK | Week 3
Finally we have something showing on the screen. There is lot of boilerplate code required for Vulkan before we can actually do something meaningful. The foundation which is built during this week will be basis of our project and everything we are going to build on top of it.
Howdy Everyone! If you’re regular visitor and here to see my progress on this project, I am glad to see you here. If you’re new visitor, You might like to start from my first blogpost when I started working on this project from scratch. Thanks for visiting.
Allright, so during my last 1:1 meeting with my Professor Dr. Varcholik, he suggested me to reboot and use boilerplate code rather than writing everything from scratch. He told me that boilerplate code is called “Boilerplate” for a reason and there is no point reinventing the wheel because it’s just making me more slow. So I’ve decided to use already existing boilerplate from internet.
But there is a catch, as we are using Vulkan-App ( C++ wrapper for Vulkan ), there aren’t many code samples available online especially about pipeline, depth buffer and vertex / index buffers initialization. Before we can render cube, these are the prioritized tasks that I’ve listed out.Create a Vulkan Instance.
Create Swapchain from logical device.Create Image Views.Create Primary Render PassCreate Vertex and Fragment shaders in GLSL and Compile it to SPIR-VCreate Graphics Pipeline to represent Entire state.Create Command Pool.Create Command Buffers.Create Synchronization primitives.- Create depth attachment which will go into render pass.
- Create Vertex and Index buffers to load data directly from 3d model (Partial done)
Create commands for each command buffer to render cube.
( Strikethrough indicates all the tasks I’ve completed this week )
These tasks are necessary to be completed whether you want to render a triangle or cube. Process is the same. I have postponed Texturing part as goal is to have something on screen first.
btw, Feel free to visit my GitHub repository to checkout my project and download code files.
Link to This Project’s GitHub Repository
You can go to “releases” section on my GitHub repo and download zip file under tag “Week_III_Progress“. So You can look into the code which I’m referencing here.
Lets dive into what I’ve done this week. So out of these 11 subtasks, I’ve completed roughly 10 tasks. Creating Vertex and Index buffers and attaching it to Pipeline took me too much time than I thought. Vulkan Hpp api doesn’t map directly to old counterparts as working with handles is tricky. I’m still debugging fatal crash related to vk::MemoryRequirements which is blocker for me as of now.
One thing I’ve changed in last implementation is Change in Validation Layer name. Previously it was VK_LAYER_KHRONOS_validation but its not supported on older Vulkan API so I’ve changed it to VK_LAYER_LUNARG_standard_validation. Also, for swap chain, I’ve added new Device Extension called VK_KHR_swapchain.
Looking at the code, All new changes follow the same design principle we are using since beginning. we have new methods with the same names as tasks in our InitializeVulkan() method. First one is CreateSwapChain() method. As Vulkan doesn’t have default frame buffer, we are going to provide separate infrastructure to which we can render to before presentation on screen. It’s called as Swapchain. Using Surface capabilities, formats, Image format and Extent, we have created swap chain and created swap chain images vector array.
Second method is CreateImageViews(). This function creates basic image view for every image in the swap chain.
Third method is CreateRenderPass(). While creating a pipeline, we need to tell Vulkan about frame buffer attachments that will be used while rendering. Currently it includes Color Attachments, color Attachment reference, Subpass and Dependency.
Next method have probably the biggest implementation so far. It deals with 2 tasks. Compiling GLSL to SPIR-V and creating Graphics pipeline. We’ve named it as CreateGraphicsPipeline(). We have used libshaderc library for compiling Vertex and fragment shader strings into SPIR-V which are used for building first part of graphics pipeline. Then we have many stages viz., VertexInputStateInfo, InputAssembly, Viewport, Scissor, Rasterizer, Multisampling, ColorBlendAttachment. Finally we combine everything into GraphicsPipelineCreateInfo structure to create Pipeline.
In the next tasks, we set Framebuffer for each image view and create Unique command pool associated with Unique Command Buffers. We iterate through every command buffer to bind pipeline, bind Vertex buffer and Index buffers ( Which is I am currently working on ). All binding methods are called between beginRenderPass() and endRenderPass() methods. Before we end Render Pass for specific command buffer, we call draw method with vertex count and instance count.
For Synchronization, we have created 2 Semaphores viz., ImageAvailableSemaphore and RenderFinishedSemaphore to indicate that image is acquired and ready for rendering and another one for rendering has finished and presentation can happen.
In the last, we revisited our Draw() method to draw frame. In this step, we acquire image from swap chain and submitting the result back to the swap chain to have it eventually show up on the screen.
So collectively more than 1000 lines of codes, we have triangle rendering on the screen. It should look like this on screen.


Next Week Task:-
So, for next week, My goal is to complete Importing 3D model using any Asset loading library like Tinyobjloader and Texturing That model and complete backlog tasks.
I hope that you’ve found this dev diary informative and useful. Feel free to comment down below on what do you think and also if you have any questions or requests, You’re most welcome! Stay Tuned!
Thanks for visiting. Have a great day ahead.. 🙂