Featured Article

Vulkan Hello Triangle Tutorial

Cynthia Jul 13, 2026

Vulkan, an advanced graphics and compute API, is at the forefront of modern desktop and mobile graphics, gaming, and high-performance computing. For many developers looking to dive into Vulkan, understanding how to create a simple "hello triangle" example is a crucial first step. This tutorial will guide you through creating a Vulkan "hello triangle" application, optimizing your understanding and opening the door to more complex Vulkan projects.

a white triangle on a black background
a white triangle on a black background

Before we begin, ensure you have a basic understanding of modern graphics pipelines and C++, as well as access to a GPU that supports Vulkan. Additionally, you'll need to set up a Vulkan SDK, which includes essential headers, libraries, and tools.

the structure of a volcano is shown in this graphic above it's main features
the structure of a volcano is shown in this graphic above it's main features

Setting Up the Environment

To start, create a new C++ project and include the necessary Vulkan and GLFW headers. GLFW is a cross-platform library for creating windows, contexts, and surfaces, which Vulkan requires.

the layers of an active volcano diagram with labeled labels on white background - stock image
the layers of an active volcano diagram with labeled labels on white background - stock image

```cpp #include #define GLFW_INCLUDE_VULKAN #include ```

Initializing GLFW and Creating a Window

LIB-BS016
LIB-BS016

Initialize GLFW and create a window where your triangle will be rendered.

```cpp glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(800, 600, "Hello Triangle", nullptr, nullptr); ```

Setting Up Vulkan Instance and Debug Features

an image of the inside of a volcano with its layers labeled in english and spanish
an image of the inside of a volcano with its layers labeled in english and spanish

Create a Vulkan instance, enabling validation layers for better debugging and integrating it with GLFW.

```cpp VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Hello Triangle"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; // Enable validation layers for debugging createInfo.enabledExtensionCount = 0; // No additional extensions needed createInfo.ppEnabledExtensionNames = nullptr; VkDebugReportCallbackCreateInfoEXT debugCreateInfo{}; debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debugCreateInfoFlagsEXT debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; debugCreateInfo.pfnCallback = myDebugCallback; VkInstance instance; if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { // Handle failure to create instance } VkDebugReportCallbackEXT callback; if (CreateDebugReportCallbackEXT(instance, &debugCreateInfo, nullptr, &callback) != VK_SUCCESS) { // Handle failure to create debug callback } ```

Enumerating Physical Devices and Choosing a GPU

a black and white image of a triangle
a black and white image of a triangle

List available GPUs and select one that supports Vulkan. Physical devices represent the hardware components of your system, such as GPUs.

```cpp uint32_t deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); std::vector devices(deviceCount); if (vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()) != VK_SUCCESS) { // Handle failure to enumerate devices } VkPhysicalDevice physicalDevice = devices[0]; // Choose the first device for simplicity ```

someone is holding up a paper cutout to show how it looks like they are doing something
someone is holding up a paper cutout to show how it looks like they are doing something
Teaching resources
Teaching resources
a white triangle on a black background
a white triangle on a black background
the cross section of a volcano
the cross section of a volcano
what is a volcano? info poster with information about the structure and its main features
what is a volcano? info poster with information about the structure and its main features
Volcanic eruption
Volcanic eruption
Grinch, Tattoos
Grinch, Tattoos
a black and white triangle logo on a white background
a black and white triangle logo on a white background
an orange triangle on a white background
an orange triangle on a white background

Creating a Logical Device

Create a logical device, which serves as an interface to a physical device. Request queues for graphics rendering and present frames to the screen.

```cpp VkDeviceQueueCreateInfo queueCreateInfo{}; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.queueFamilyIndex = 0; // Graphics queue family queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = priorities.data(); VkDeviceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.pQueueCreateInfos = &queueCreateInfo; createInfo.queueCreateInfoCount = 1; // Add other features and required extensions as needed VkDevice device; if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) { // Handle failure to create device } vkGetDeviceQueue(device, 0, 0, &graphicsQueue); ```

Creating Surface and Swap Chain

Create a surface for the window and a swap chain with image buffers for rendering.

oum

Creating Pipeline Stages: Vertex and Fragment Shaders

Define the vertex and fragment shaders for your triangle, using the GLSL shading language. Vulkan shaders are written in SPIR-V, so you'll need to compile your GLSL code with a tool like glslc.

Vertex Shader

```glsl #version 450 layout (location = 0) in vec2 vertexPosition; // Position attribute out vec2 vUV; // UV (Texture coordinates) output void main() { gl_Position = vec4(vertexPosition, 0.0, 1.0); // Vertex position vUV = vertexPosition; // Output texture coordinates } ```

Fragment Shader

```glsl #version 450 in vec2 vUV; // UV (Texture coordinates) input layout (location = 0) out vec4 fragmentColor; // Output color void main() { fragmentColor = vec4(vUV.x, abs(vUV.y), 0.0, 1.0); // Color vertex based on UV coordinates } ```

Creating Pipeline Layout, Pipeline, and Command Buffer

Set up a pipeline layout, which describes the binding of shader resources, and create a graphics pipeline.

With the pipeline layout and graphics pipeline created, generate a command buffer to record drawing commands.

Rendering the Triangle

Begin rendering your triangle by submitting the command buffer, presenting frames, and looping until the window is closed.

Congratulations! You've just created a Vulkan "hello triangle" example. The journey to mastering Vulkan has begun, and more complex applications await your exploration. Happy coding!