o
odinpkg.dev
packages / library / vulkan-tutorial-odin

vulkan-tutorial-odin

2c05c0alibrary

Vulkan tutorial written in Odin

MIT ยท updated 2 years ago

Vulkan Tutorial

Vulkan tutorial written in Odin.

result

Introduction

This repository will follow the structure of the original tutorial. Each commit will correspond to one page or on section of the page for long chapters.

Sometimes an 'extra' commit will be added with some refactoring, commenting or feature.

There are a few more things covered in the more branch.

Requirements

You need to have a Vulkan SDK and the Odin compiler.

Running the project

# if you need to recompile the shaders
.\scripts\compile_shaders.ps1
# or ./scripts/compile_shaders.sh on linux

# compile and run the application
odin run .

# or with validation layers
odin run . -define:ENABLE_VALIDATION_LAYERS=true

Commits

This section contains the summary of the project commits. Follow ๐Ÿ‡ to go to the related tutorial page and ๐Ÿ˜ผ to go to the commit details.

1.1.1: Base code ๐Ÿ‡ ๐Ÿ˜ผ

GLFW initialization, window's creation and main loop setup.

1.1.2: Instance ๐Ÿ‡ ๐Ÿ˜ผ

Create and destroy the Vulkan instance.

1.1.3: Validation layers ๐Ÿ‡ ๐Ÿ˜ผ

Enable VK_LAYER_KHRONOS_validation validation layer and setup the debug messenger.

Here we make use of Odin's command-line defines to control the activation of the validation layers (see here).

1.1.4: Physical devices and queue families ๐Ÿ‡ ๐Ÿ˜ผ

Physical device and queue families selection.

1.1.5: Logical device and queues ๐Ÿ‡ ๐Ÿ˜ผ

Create the logical device and retrieve a graphics queue.

1.2.1: Window surface ๐Ÿ‡ ๐Ÿ˜ผ

Create the window surface and retrieve a queue supporting presentation.

1.2.2: Swapchain ๐Ÿ‡ ๐Ÿ˜ผ

Create the swapchain and retriving the swapchain images.

1.2.3: Image views ๐Ÿ‡ ๐Ÿ˜ผ

Create the image views for the swapchain images.

1.3.2: Shader modules ๐Ÿ‡ ๐Ÿ˜ผ

Create and compile the vertex and fragment shaders, load them, and the shader modules.

1.3.3: Fixed functions ๐Ÿ‡ ๐Ÿ˜ผ

Setup the states of the fixed functions of the graphics pipeline and create the pipeline layout.

1.3.4: Render passes ๐Ÿ‡ ๐Ÿ˜ผ

Create the render pass describing the attachments to use during rendering.

1.3.5: Graphics pipeline conclusion ๐Ÿ‡ ๐Ÿ˜ผ

Finish the graphics pipeline creation.

1.4.1: Framebuffers ๐Ÿ‡ ๐Ÿ˜ผ

Create the swapchain framebuffers from the swapchain image views and the render pass.

1.4.2: Command buffers ๐Ÿ‡ ๐Ÿ˜ผ

Create the command buffer and record commands to draw.

1.4.3: Rendering and presentation ๐Ÿ‡ ๐Ÿ˜ผ

Finalize drawing the triangle to the screen!

1.4.4: Frames in flight ๐Ÿ‡ ๐Ÿ˜ผ

Improve rendering by allowing overlap between cpu and gpu with multiple frames in flight.

1.5: Swap chain recreation ๐Ÿ‡ ๐Ÿ˜ผ

Handle swapchain recreation and window's resize.

There is a bit of factoring around the swapchain creation and its dependencies here.

Resizing detection is also done differently, glfwSetFramebufferSizeCallback is not used and we just manually check if the framebuffer was resized with glfwGetFramebufferSize.

2.1: Vertex input description ๐Ÿ‡ ๐Ÿ˜ผ

Move hardcoded vertices from the vertex shader to the application code and update pipeline's vertex input info.

A new vertex.odin file is added to keep things more manageable.

2.2: Vertex buffer creation ๐Ÿ‡ ๐Ÿ˜ผ

Create the actual vertex buffer and its memory, fill it and bind it before drawing.

2.3: Staging buffer ๐Ÿ‡ ๐Ÿ˜ผ

Create a buffer whose memory is local to the graphics card and a staging buffer from which data is tranfered.

2.4: Index buffer ๐Ÿ‡ ๐Ÿ˜ผ

Render a rectangle without duplicating vertices by using an index buffer.

3.1: Descriptor layout and buffer ๐Ÿ‡ ๐Ÿ˜ผ

Update the vertex shader to apply a transformation and render it with a perspective camera. Also create the descriptor set layout, the buffers used to send data to the shader and update it each frame.

3.2: Descriptor pool and sets ๐Ÿ‡ ๐Ÿ˜ผ

Create the descriptor set pool and sets, update them to point at the proper buffers and bind them before rendering.

4.1: Images ๐Ÿ‡ ๐Ÿ˜ผ

Load an image file and upload its data to the GPU.

4.2: Image view and sampler ๐Ÿ‡ ๐Ÿ˜ผ

Create the image view and sampler and enable anisotropic filtering.

4.3: Combined image sampler ๐Ÿ‡ ๐Ÿ˜ผ

Update the descriptor sets, Vertex structure and shaders to use the loaded image as a texture for the displayed rectangle.

5: Depth buffering ๐Ÿ‡ ๐Ÿ˜ผ

Render overlapping geometry, create a depth texture and set up depth testing.

6.0: Obj file loader ๐Ÿ˜ผ

This is not part of the original Vulkan tutorial!

Implement a simple (and most likely incomplete) loader for .obj files in preparation for the next chapter. It overlaps a little with the next chapter though as it already merges duplicate vertices and invert the texture coordinates y axis.

This is a very simple loader, it might not work for other more complicated loader. Also it only outputs positions and texture coordinate since we won't use normals.

6: Loading models ๐Ÿ‡ ๐Ÿ˜ผ

Load an .obj model and render it.

Since we don't use the vertex color anymore I just remove them altogether.

The tutorial already mentions it but the model doesn't play nicely with backface culling so I disabled it.

7: Generating Mipmaps ๐Ÿ‡ ๐Ÿ˜ผ

Generate mipmaps for the model texture and update sampler to make use of the new mip levels.

Model rotation is now controlled with the right and left keys.

8: Multisampling ๐Ÿ‡ ๐Ÿ˜ผ

Add MSAA support.

Extra.2: Cleanup and refactoring ๐Ÿ˜ผ

This is not part of the original Vulkan tutorial!

Clean up the code, refactor to avoid passing to many things around all the time, make to code more "Odin-like" by applying idioms from the language.