Skip to content

Commit 9059eef

Browse files
Add project template, update project setup documentation (#342)
* Add standalone Vulkan application template * Use first chapter as project template * Expand CMake setup with actual examples Add template setup Move CMake section
1 parent e0511f4 commit 9059eef

5 files changed

Lines changed: 255 additions & 15 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ attachments/simple_engine/android/app/build/**
3030
attachments/simple_engine/android/gradle/wrapper/**
3131
attachments/simple_engine/android/gradlew
3232
attachments/simple_engine/android/gradlew.bat
33+
34+
attachments/template/build/**
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
cmake_minimum_required (VERSION 3.29)
2+
3+
set (TEMPLATE_NAME "VulkanTutorial")
4+
5+
project (${TEMPLATE_NAME})
6+
7+
# Add option to enable/disable C++ 20 module
8+
option(ENABLE_CPP20_MODULE "Enable C++ 20 module support for Vulkan" OFF)
9+
10+
# Enable C++ module dependency scanning only if C++ 20 module is enabled
11+
if(ENABLE_CPP20_MODULE)
12+
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
13+
endif()
14+
15+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
16+
17+
find_package(glfw3 REQUIRED)
18+
find_package(glm REQUIRED)
19+
find_package(Vulkan 1.4.335 REQUIRED)
20+
find_package(tinyobjloader REQUIRED)
21+
find_package(tinygltf REQUIRED)
22+
find_package(KTX REQUIRED)
23+
24+
# Set up Vulkan C++ module only if enabled
25+
if(ENABLE_CPP20_MODULE)
26+
add_library(VulkanCppModule)
27+
add_library(Vulkan::cppm ALIAS VulkanCppModule)
28+
29+
target_compile_definitions(VulkanCppModule PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1)
30+
target_include_directories(VulkanCppModule PUBLIC "${Vulkan_INCLUDE_DIR}")
31+
target_link_libraries(VulkanCppModule PUBLIC Vulkan::Vulkan)
32+
33+
set_target_properties(VulkanCppModule PROPERTIES CXX_STANDARD 20)
34+
35+
# Add MSVC-specific compiler options for proper C++ module support
36+
if(MSVC)
37+
target_compile_options(VulkanCppModule PRIVATE
38+
/std:c++latest # Use latest C++ standard for better module support
39+
/permissive- # Standards conformance mode
40+
/Zc:__cplusplus # Enable correct __cplusplus macro
41+
/EHsc # Enable C++ exception handling
42+
/Zc:preprocessor # Use conforming preprocessor
43+
/translateInclude # Automatically translate #include to import for standard library
44+
)
45+
endif()
46+
47+
target_sources(VulkanCppModule
48+
PUBLIC
49+
FILE_SET cxx_modules TYPE CXX_MODULES
50+
BASE_DIRS
51+
"${Vulkan_INCLUDE_DIR}"
52+
FILES
53+
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
54+
)
55+
56+
57+
# Add the vulkan.cppm file directly as a source file
58+
target_sources(VulkanCppModule
59+
PRIVATE
60+
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
61+
)
62+
else()
63+
# Create a dummy interface library when C++ 20 module is disabled
64+
add_library(VulkanCppModule INTERFACE)
65+
add_library(Vulkan::cppm ALIAS VulkanCppModule)
66+
target_link_libraries(VulkanCppModule INTERFACE Vulkan::Vulkan)
67+
target_compile_definitions(VulkanCppModule
68+
INTERFACE VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
69+
)
70+
endif()
71+
72+
find_package(stb REQUIRED)
73+
set(STB_INCLUDEDIR ${stb_INCLUDE_DIRS})
74+
75+
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
76+
77+
set(TEMPLATE_DIR ${CMAKE_BINARY_DIR}/${TEMPLATE_NAME})
78+
79+
add_executable (${TEMPLATE_NAME} main.cpp)
80+
set_target_properties (${TEMPLATE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${TEMPLATE_DIR})
81+
set_target_properties (${TEMPLATE_NAME} PROPERTIES CXX_STANDARD 20)
82+
target_link_libraries (${TEMPLATE_NAME} Vulkan::cppm glfw)
83+
target_include_directories (${TEMPLATE_NAME} PRIVATE ${STB_INCLUDEDIR})
84+
85+
# Add compile definition if C++ 20 module is enabled
86+
if(ENABLE_CPP20_MODULE)
87+
target_compile_definitions(${TEMPLATE_NAME} PRIVATE USE_CPP20_MODULES=1)
88+
endif()
89+
90+
# Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code
91+
target_compile_definitions(${TEMPLATE_NAME} PRIVATE "VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS" )
92+
93+
if(WIN32)
94+
if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
95+
set_target_properties(${TEMPLATE_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${TEMPLATE_DIR})
96+
endif()
97+
endif()
98+
99+
# Slang shader
100+
set (SHADER_TARGET ${TEMPLATE_NAME}Shader)
101+
set (SHADERS_DIR ${TEMPLATE_DIR}/shaders)
102+
set (SHADER_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/shader.slang")
103+
set (ENTRY_POINTS -entry vertMain -entry fragMain)
104+
add_custom_command(OUTPUT ${SHADERS_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR})
105+
add_custom_command(
106+
OUTPUT ${SHADERS_DIR}/slang.spv
107+
COMMAND ${SLANGC_EXECUTABLE} ${SHADER_SOURCES} -target spirv -profile spirv_1_4 -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o ${TEMPLATE_DIR}/shaders/slang.spv
108+
WORKING_DIRECTORY ${SHADERS_DIR}
109+
DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES}
110+
COMMENT "Compiling Slang Shaders"
111+
VERBATIM
112+
)
113+
add_custom_target(${SHADER_TARGET} DEPENDS ${SHADERS_DIR}/slang.spv)
114+
add_dependencies(${TEMPLATE_NAME} ${SHADER_TARGET})
115+
116+
# Assets
117+
set (ASSET_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../assets/")
118+
file (COPY ${ASSET_DIR}/viking_room.obj DESTINATION ${TEMPLATE_DIR}/models)
119+
file (COPY ${ASSET_DIR}/viking_room.png DESTINATION ${TEMPLATE_DIR}/textures)

attachments/template/main.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include <memory>
2+
#if defined(__INTELLISENSE__) || !defined(USE_CPP20_MODULES)
3+
# include <vulkan/vulkan_raii.hpp>
4+
#else
5+
import vulkan_hpp;
6+
#endif
7+
#include <GLFW/glfw3.h>
8+
9+
#include <cstdlib>
10+
#include <iostream>
11+
#include <stdexcept>
12+
13+
const uint32_t WIDTH = 800;
14+
const uint32_t HEIGHT = 600;
15+
16+
class HelloTriangleApplication
17+
{
18+
public:
19+
void run()
20+
{
21+
initWindow();
22+
initVulkan();
23+
mainLoop();
24+
cleanup();
25+
}
26+
27+
private:
28+
GLFWwindow *window = nullptr;
29+
30+
void initWindow()
31+
{
32+
glfwInit();
33+
34+
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
35+
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
36+
37+
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
38+
}
39+
40+
void initVulkan()
41+
{
42+
}
43+
44+
void mainLoop()
45+
{
46+
while (!glfwWindowShouldClose(window))
47+
{
48+
glfwPollEvents();
49+
}
50+
}
51+
52+
void cleanup()
53+
{
54+
glfwDestroyWindow(window);
55+
56+
glfwTerminate();
57+
}
58+
};
59+
60+
int main()
61+
{
62+
try
63+
{
64+
HelloTriangleApplication app;
65+
app.run();
66+
}
67+
catch (const std::exception &e)
68+
{
69+
std::cerr << e.what() << std::endl;
70+
return EXIT_FAILURE;
71+
}
72+
73+
return EXIT_SUCCESS;
74+
}

attachments/template/shader.slang

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
struct VSInput {
2+
float3 inPosition;
3+
float3 inColor;
4+
float2 inTexCoord;
5+
};
6+
7+
struct UniformBuffer {
8+
float4x4 model;
9+
float4x4 view;
10+
float4x4 proj;
11+
};
12+
ConstantBuffer<UniformBuffer> ubo;
13+
14+
struct VSOutput
15+
{
16+
float4 pos : SV_Position;
17+
float3 fragColor;
18+
float2 fragTexCoord;
19+
};
20+
21+
[shader("vertex")]
22+
VSOutput vertMain(VSInput input) {
23+
VSOutput output;
24+
output.pos = mul(ubo.proj, mul(ubo.view, mul(ubo.model, float4(input.inPosition, 1.0))));
25+
output.fragColor = input.inColor;
26+
output.fragTexCoord = input.inTexCoord;
27+
return output;
28+
}
29+
30+
Sampler2D texture;
31+
32+
[shader("fragment")]
33+
float4 fragMain(VSOutput vertIn) : SV_TARGET {
34+
return texture.Sample(vertIn.fragTexCoord);
35+
}

en/02_Development_environment.adoc

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -278,21 +278,6 @@ image::/images/library_directory.png[]
278278

279279
Tinyobjloader can be installed with vcpkg like so: vcpkg install tinyobjloader
280280

281-
=== Setting up Visual Studio
282-
283-
==== Setting up a CMake project
284-
285-
Now that you have installed all the dependencies, we can set up a basic
286-
CMake project for Vulkan and write a little bit of code to make sure that
287-
everything works.
288-
289-
We will assume that you already have some basic experience with CMake, like
290-
how variables and rules work. If not, you can get up to speed very quickly with https://cmake.org/cmake/help/book/mastering-cmake/cmake/Help/guide/tutorial/[this tutorial].
291-
292-
You can now use the code from any of the following chapters found in the `attachment` folder as a template for your Vulkan projects. Make a copy, rename it to something like `HelloTriangle` and remove all the code in `main.cpp`.
293-
294-
Congratulations, you're all set for xref:03_Drawing_a_triangle/00_Setup/00_Base_code.adoc[playing with Vulkan]!
295-
296281
== Linux
297282

298283
These instructions will be aimed at Ubuntu, Fedora and Arch Linux users, but
@@ -515,3 +500,28 @@ You are now all set for xref:03_Drawing_a_triangle/00_Setup/00_Base_code.adoc[th
515500
== Android
516501

517502
Vulkan is a first-class API on Android and widely supported. But using it differs in several key areas from window management to build systems. So while the basic chapters focus on desktop platforms, the tutorial also has a xref:14_Android.adoc[dedicated chapter] that walks you through setting up your development environment and getting the tutorial code up-and-running on Android.
503+
504+
== Setting up a CMake project
505+
506+
Now that you have installed all the dependencies, we can set up a basic
507+
CMake project for Vulkan and write a little bit of code to make sure that
508+
everything works.
509+
510+
We will assume that you already have some basic experience with CMake, like
511+
how variables and rules work. If not, you can get up to speed very quickly with https://cmake.org/cmake/help/book/mastering-cmake/cmake/Help/guide/tutorial/[this tutorial].
512+
513+
The `attachment\template` folder contains a CMake template that you can use to create a project file in the `build` folder for your IDE of choice. Use this as a starting point to work along the tutorial:
514+
515+
----
516+
cd attachments\template
517+
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=[path\to\vcpkg]\scripts\buildsystems\vcpkg.cmake
518+
----
519+
520+
Alternatively you can do the same in the `attachments` folder, which will create a project with all chapters from the tutorial:
521+
522+
----
523+
cd attachments
524+
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=[path\to\vcpkg]\scripts\buildsystems\vcpkg.cmake
525+
----
526+
527+
Congratulations, you're all set for xref:03_Drawing_a_triangle/00_Setup/00_Base_code.adoc[playing with Vulkan]!

0 commit comments

Comments
 (0)