Rust Light Vulkan Engine
This is a translation of Brendan Galea's Vulkan tutorial into rust using the Ash crate.
Original tutorial: Brendan Galea's YouTube Page
Each commit will correspond to a video from this tutorial.
Requirements
You will need to have the LunarG Vulkan SDK installed and on linux you will need to add the library and layers to your path.
Things to Note
- Unlike the tutorial, this translation will use the winit window API as it is fully written in rust. This will result in some large deviations from the videos.
- Due to the methodology of rust being incredibly different to that of C++, the structure of the code will be different in some areas. These changes will be highlighted with a hopefully correct :) explanation of why this is the case.
- To get the most out of the tutorial, I recommend trying to follow along with the video and translate the code yourself and use this repository if you get stuck or want to copy large amounts of code (such as videos 3, 4, and 5).
To use the logging functionality in this code, you need to set the RUST_LOG
environment variable:
Windows PowerShell
$env:RUST_LOG="debug"
Linux
RUST_LOG=vulkan_tutorial_ash=debug cargo run
More information about using this crate can be found in the documentation.
Acknowledgements
Big thanks to Brendan Galea for making the tutorial that this code is based on, and Alexander Overvoorde for making The Vulkan Tutorial that I first learnt Vulkan from. Also thanks to Adrien Ben for translating Alex's tutorial, a bunch of this code was yoinked from that repo :)
link)
1: Opening a Window (- Later versions of winit (0.20+) use an architecture that is very different to glfw. Because of this the structure presented in the tutorial will not work, or will be very weird to implement. As such, there is no lve_window struct and ownership of the window has been moved to the application (first_app).
link)
2: Graphics Pipeline Overview (- A
build.rs
file was added to compile the shader files when the program is built. This is just a replacement for the shell script presented in the video. - "We're about half way to seeing our first triangle on screen"... I've never heard a more blatant lie.
link)
3: Device Setup & Pipeline cont. (- Due to the nature of Rust, a lot of the functions that were
void
in the tutorial now return things. This is so we can properly initialise theLveDevice
struct by allowing the functions to borrow these Vulkan structs. device_extensions
does is not a global constant anymore as ash requires the extension names to be given by a functions, and hence can't be stored in a constant. It can now be found in theLveDevice::get_device_extensions()
function.- Due to the lack of lve_window module, it was more convenient to use the
create_surface()
function from the ash-window crate in theLveDevice::create_surface()
function. The naming here is a little confusing, sorry about that. - You will also note that ash has two surface types,
Surface
andvk::SurfaceKHR
. The former is a struct containing the functions that act on the surface, while the latter is the Vulkan surface itself. - The biggest deviation in this code is the fact that the
lve_device
now owns thepipeline
instead of the application owning both. In the tutorial, Brendan says that having a reference to the device in the pipeline can be unsafe as the device needs to be destroyed after the pipeline. In Rust, if it can be unsafe it won't compile, so some restructuring had to be done.
- Overall, the way that extensions are handled in this implementation are slightly different so don't expect the exact same console output as the one shown in the video.
link)
4: Fixed Function Pipeline Stages (- Some pipeline builder functions were commented out as they were optional and required null pointers, something I'm not sure is implemented in rust.
- Pipeline destructor function was already implemented in the previous commit