Vulkan Tutorial in C - 001 - Initial Setup
You can find the full source code here.
Why Use C?
- I prefer C over C++.
- There are already many Vulkan tutorials available in C++.
- C is a straightforward language, making it ideal for beginners (and tutorials).
- Avoid OOP, Clean Code, RAII, templates, etc.
Installing the Vulkan SDK
You’ll need to download and install the Vulkan SDK:- Go to https://www.vulkan.org/ and download the latest version of the Vulkan SDK.
- The installer will place the Vulkan SDK in a default directory, typically something like C:\VulkanSDK\1.x.x.x. You can also choose a custom directory during the installation process. Regardless of what you do, keep this directory in mind since we'll need it.
Windows: Note on Microsoft Visual Studio
On Windows, I recommend using Microsoft Visual Studio with the Visual C++ tools, as well as the command-line compiler (CL). I'm going to use that to compile the code using a build.bat script.If you don’t have Visual Studio installed, you can download the free Community Edition here: https://visualstudio.microsoft.com/vs/community/.
Windows: Compiling the Vulkan Application
I'll compile the project using a build.bat script. I'll place it in the same directory as my main.c file:
@echo off
REM Vulkan paths
set vki=-I"C:\VulkanSDK\1.x.x.x\Include"
set vkl=-LIBPATH:"C:\VulkanSDK\1.x.x.x\Lib"
REM Compiler flags
set cf=-nologo -FC -Z7 -W4 -WX -wd4189 -wd4100 -wd4101
IF NOT EXIST bin mkdir bin
pushd bin
cl %cf% ..\main.c %vki% -link %vkl% user32.lib vulkan-1.lib
popd
REM Vulkan paths
set vki=-I"C:\VulkanSDK\1.x.x.x\Include"
set vkl=-LIBPATH:"C:\VulkanSDK\1.x.x.x\Lib"
REM Compiler flags
set cf=-nologo -FC -Z7 -W4 -WX -wd4189 -wd4100 -wd4101
IF NOT EXIST bin mkdir bin
pushd bin
cl %cf% ..\main.c %vki% -link %vkl% user32.lib vulkan-1.lib
popd
That's a standard script I use to compile every project. It's based on what Casey Muratori did in Handmade Hero. It does the following:
- Sets up the include and library paths for Vulkan.
- Defines some compiler flags for warnings and debug symbols.
- Creates a bin folder if it doesn’t exist.
- Compiles main.c, linking it with user32.lib and vulkan-1.lib.
Make sure to adjust the Vulkan SDK path (C:\VulkanSDK\1.x.x.x) to the specific location and version you've installed!
To build the project, we'll open the x64 Native Tools Command Prompt for VS 20xx that came with Visual Studio, navigate to the directory where we've saved the build.bat and main.c files, then type build and press enter.Note: This won't work just yet because we haven’t written the minimum steps required in main.c, but once that's done, this is how we'll compile the app.
The app structure
Here's an overview of the app's structure:
// Includes and helpful utilities
// VulkanContext struct
// File loading utility
// globalRunning and WindowProc
// Vulkan Validation layer's Debug Callback
// Vulkan Initialization Function
// Create shader module function
// WinMain application entry point
// VulkanContext struct
// File loading utility
// globalRunning and WindowProc
// Vulkan Validation layer's Debug Callback
// Vulkan Initialization Function
// Create shader module function
// WinMain application entry point
Setting Up Vulkan Includes
Now that we have the basic setup out of the way, we can include the necessary headers in main.c:
#include <windows.h> // Must be included before vulkan_win32.h
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_win32.h>
It turns out windows.h must be included before vulkan_win32.h, but from my tests, we don’t need it before vulkan.h.#include <vulkan/vulkan.h>
#include <vulkan/vulkan_win32.h>
Though, I'll keep windows.h before vulkan.h anyway because... OCD.
Do I need VK_USE_PLATFORM_WIN32_KHR?
I've seen some Vulkan tutorials and documentation mention defining VK_USE_PLATFORM_WIN32_KHR before including vulkan_win32.h.
But from my tests, that doesn't seem necessary at least on my Windows PC.
Since I don't know why we would ever need that, I'll keep the code without it for now.
I've seen some Vulkan tutorials and documentation mention defining VK_USE_PLATFORM_WIN32_KHR before including vulkan_win32.h.
But from my tests, that doesn't seem necessary at least on my Windows PC.
Since I don't know why we would ever need that, I'll keep the code without it for now.
Useful Includes and Type Definitions
I like to have these in my codebases, so I'll define it here:
#include <assert.h> // For assertions
#include <stdbool.h> // For booleans
#include <stdint.h> // For fixed-width integers
#include <stdio.h> // For printing
// Custom integer types
typedef uint8_t u8;
typedef uint32_t u32;
typedef int32_t s32;
// Custom float type
typedef float f32;
// Helper macro to get the count of elements in an array
#define array_count(array) (sizeof(array) / sizeof((array)[0]))
You don't have to keep these, but you'll need to update the code everywhere if you intend to copy and paste.
#include <stdbool.h> // For booleans
#include <stdint.h> // For fixed-width integers
#include <stdio.h> // For printing
// Custom integer types
typedef uint8_t u8;
typedef uint32_t u32;
typedef int32_t s32;
// Custom float type
typedef float f32;
// Helper macro to get the count of elements in an array
#define array_count(array) (sizeof(array) / sizeof((array)[0]))
I Won’t Use 'Frames in Flight' (at least for now)
The concept of "frames in flight" is pretty confusing. I'm having enough trouble with Vulkan as it is, so I'll just avoid having multiple frames in flight altogether, at least to start. I may come back later once I'm confident to try and tackle that as well.Conclusion
In the next post, we'll start with the VulkanContext struct, which will hold some of the Vulkan state necessary for basically any Vulkan app.Next
Comments
Post a Comment