Skip to content

Commit 4b4c133

Browse files
committed
Add support for glTF and KTX textures with improved dependency management
- Expanded Linux, Windows, and Android scripts to include `tinygltf`, `nlohmann-json`, and `KTX` dependencies. - Introduced `FindKTX.cmake` and `FindTinyGLTF.cmake` for cross-platform library handling with fallback to FetchContent if unavailable. - Added `35_gltf_ktx` chapter featuring glTF model and KTX texture integration in Vulkan, with Android and desktop support. - Enhanced Gradle and CMake configurations for selective chapter builds and streamlined dependencies.
1 parent 0e90d7b commit 4b4c133

File tree

13 files changed

+2226
-7
lines changed

13 files changed

+2226
-7
lines changed

attachments/35_gltf_ktx.cpp

Lines changed: 1408 additions & 0 deletions
Large diffs are not rendered by default.

attachments/CMake/FindKTX.cmake

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# FindKTX.cmake
2+
#
3+
# Finds the KTX library
4+
#
5+
# This will define the following variables
6+
#
7+
# KTX_FOUND
8+
# KTX_INCLUDE_DIRS
9+
# KTX_LIBRARIES
10+
#
11+
# and the following imported targets
12+
#
13+
# KTX::ktx
14+
#
15+
16+
# Check if we're on Linux - if so, we'll skip the search and directly use FetchContent
17+
if(UNIX AND NOT APPLE)
18+
# On Linux, we assume KTX is not installed and proceed directly to fetching it
19+
set(KTX_FOUND FALSE)
20+
else()
21+
# On non-Linux platforms, try to find KTX using pkg-config first
22+
find_package(PkgConfig QUIET)
23+
if(PKG_CONFIG_FOUND)
24+
pkg_check_modules(PC_KTX QUIET ktx libktx ktx2 libktx2)
25+
endif()
26+
27+
# Try to find KTX using standard find_package
28+
find_path(KTX_INCLUDE_DIR
29+
NAMES ktx.h
30+
PATH_SUFFIXES include ktx KTX ktx2 KTX2
31+
HINTS
32+
${PC_KTX_INCLUDEDIR}
33+
/usr/include
34+
/usr/local/include
35+
$ENV{KTX_DIR}/include
36+
$ENV{VULKAN_SDK}/include
37+
${CMAKE_SOURCE_DIR}/external/ktx/include
38+
)
39+
40+
find_library(KTX_LIBRARY
41+
NAMES ktx ktx2 libktx libktx2
42+
PATH_SUFFIXES lib lib64
43+
HINTS
44+
${PC_KTX_LIBDIR}
45+
/usr/lib
46+
/usr/lib64
47+
/usr/local/lib
48+
/usr/local/lib64
49+
$ENV{KTX_DIR}/lib
50+
$ENV{VULKAN_SDK}/lib
51+
${CMAKE_SOURCE_DIR}/external/ktx/lib
52+
)
53+
54+
include(FindPackageHandleStandardArgs)
55+
find_package_handle_standard_args(KTX
56+
REQUIRED_VARS KTX_INCLUDE_DIR KTX_LIBRARY
57+
)
58+
59+
# Debug output if KTX is not found (only on non-Linux platforms)
60+
if(NOT KTX_FOUND)
61+
message(STATUS "KTX include directory search paths: ${PC_KTX_INCLUDEDIR}, /usr/include, /usr/local/include, $ENV{KTX_DIR}/include, $ENV{VULKAN_SDK}/include, ${CMAKE_SOURCE_DIR}/external/ktx/include")
62+
message(STATUS "KTX library search paths: ${PC_KTX_LIBDIR}, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64, $ENV{KTX_DIR}/lib, $ENV{VULKAN_SDK}/lib, ${CMAKE_SOURCE_DIR}/external/ktx/lib")
63+
endif()
64+
endif()
65+
66+
if(KTX_FOUND)
67+
set(KTX_INCLUDE_DIRS ${KTX_INCLUDE_DIR})
68+
set(KTX_LIBRARIES ${KTX_LIBRARY})
69+
70+
if(NOT TARGET KTX::ktx)
71+
add_library(KTX::ktx UNKNOWN IMPORTED)
72+
set_target_properties(KTX::ktx PROPERTIES
73+
IMPORTED_LOCATION "${KTX_LIBRARIES}"
74+
INTERFACE_INCLUDE_DIRECTORIES "${KTX_INCLUDE_DIRS}"
75+
)
76+
endif()
77+
else()
78+
# If not found, use FetchContent to download and build
79+
include(FetchContent)
80+
81+
# Only show the message on non-Linux platforms
82+
if(NOT (UNIX AND NOT APPLE))
83+
message(STATUS "KTX not found, fetching from GitHub...")
84+
endif()
85+
86+
FetchContent_Declare(
87+
ktx
88+
GIT_REPOSITORY https://github.com/KhronosGroup/KTX-Software.git
89+
GIT_TAG v4.3.1 # Use a specific tag for stability
90+
)
91+
92+
# Set options to minimize build time and dependencies
93+
set(KTX_FEATURE_TOOLS OFF CACHE BOOL "Build KTX tools" FORCE)
94+
set(KTX_FEATURE_DOC OFF CACHE BOOL "Build KTX documentation" FORCE)
95+
set(KTX_FEATURE_TESTS OFF CACHE BOOL "Build KTX tests" FORCE)
96+
97+
FetchContent_MakeAvailable(ktx)
98+
99+
# Create an alias to match the expected target name
100+
if(NOT TARGET KTX::ktx)
101+
add_library(KTX::ktx ALIAS ktx)
102+
endif()
103+
104+
set(KTX_FOUND TRUE)
105+
endif()
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# FindTinyGLTF.cmake
2+
#
3+
# Finds the TinyGLTF library
4+
#
5+
# This will define the following variables
6+
#
7+
# TinyGLTF_FOUND
8+
# TinyGLTF_INCLUDE_DIRS
9+
#
10+
# and the following imported targets
11+
#
12+
# tinygltf::tinygltf
13+
#
14+
15+
# First, try to find nlohmann_json
16+
find_package(nlohmann_json QUIET)
17+
if(NOT nlohmann_json_FOUND)
18+
include(FetchContent)
19+
message(STATUS "nlohmann_json not found, fetching from GitHub...")
20+
FetchContent_Declare(
21+
nlohmann_json
22+
GIT_REPOSITORY https://github.com/nlohmann/json.git
23+
GIT_TAG v3.11.2 # Use a specific tag for stability
24+
)
25+
FetchContent_MakeAvailable(nlohmann_json)
26+
endif()
27+
28+
# Try to find TinyGLTF using standard find_package
29+
find_path(TinyGLTF_INCLUDE_DIR
30+
NAMES tiny_gltf.h
31+
PATH_SUFFIXES include tinygltf
32+
)
33+
34+
include(FindPackageHandleStandardArgs)
35+
find_package_handle_standard_args(TinyGLTF
36+
REQUIRED_VARS TinyGLTF_INCLUDE_DIR
37+
)
38+
39+
if(TinyGLTF_FOUND)
40+
set(TinyGLTF_INCLUDE_DIRS ${TinyGLTF_INCLUDE_DIR})
41+
42+
if(NOT TARGET tinygltf::tinygltf)
43+
add_library(tinygltf::tinygltf INTERFACE IMPORTED)
44+
set_target_properties(tinygltf::tinygltf PROPERTIES
45+
INTERFACE_INCLUDE_DIRECTORIES "${TinyGLTF_INCLUDE_DIRS}"
46+
INTERFACE_COMPILE_DEFINITIONS "TINYGLTF_IMPLEMENTATION;TINYGLTF_NO_EXTERNAL_IMAGE;TINYGLTF_NO_STB_IMAGE;TINYGLTF_NO_STB_IMAGE_WRITE"
47+
)
48+
if(TARGET nlohmann_json::nlohmann_json)
49+
target_link_libraries(tinygltf::tinygltf INTERFACE nlohmann_json::nlohmann_json)
50+
endif()
51+
endif()
52+
else()
53+
# If not found, use FetchContent to download and build
54+
include(FetchContent)
55+
56+
message(STATUS "TinyGLTF not found, fetching from GitHub...")
57+
FetchContent_Declare(
58+
tinygltf
59+
GIT_REPOSITORY https://github.com/syoyo/tinygltf.git
60+
GIT_TAG v2.8.18 # Use a specific tag for stability
61+
)
62+
63+
# Configure tinygltf before making it available
64+
FetchContent_GetProperties(tinygltf)
65+
if(NOT tinygltf_POPULATED)
66+
FetchContent_Populate(tinygltf)
67+
68+
# Update the minimum required CMake version to avoid deprecation warning
69+
file(READ "${tinygltf_SOURCE_DIR}/CMakeLists.txt" TINYGLTF_CMAKE_CONTENT)
70+
string(REPLACE "cmake_minimum_required(VERSION 3.6)"
71+
"cmake_minimum_required(VERSION 3.10)"
72+
TINYGLTF_CMAKE_CONTENT "${TINYGLTF_CMAKE_CONTENT}")
73+
file(WRITE "${tinygltf_SOURCE_DIR}/CMakeLists.txt" "${TINYGLTF_CMAKE_CONTENT}")
74+
75+
# Create a symbolic link to make nlohmann/json.hpp available
76+
if(EXISTS "${tinygltf_SOURCE_DIR}/json.hpp")
77+
file(MAKE_DIRECTORY "${tinygltf_SOURCE_DIR}/nlohmann")
78+
file(CREATE_LINK "${tinygltf_SOURCE_DIR}/json.hpp" "${tinygltf_SOURCE_DIR}/nlohmann/json.hpp" SYMBOLIC)
79+
endif()
80+
81+
# Set tinygltf to header-only mode
82+
set(TINYGLTF_HEADER_ONLY ON CACHE BOOL "Use header only version" FORCE)
83+
set(TINYGLTF_INSTALL OFF CACHE BOOL "Do not install tinygltf" FORCE)
84+
85+
# Add the subdirectory after modifying the CMakeLists.txt
86+
add_subdirectory(${tinygltf_SOURCE_DIR} ${tinygltf_BINARY_DIR})
87+
endif()
88+
89+
# Create an alias for the tinygltf target
90+
if(NOT TARGET tinygltf::tinygltf)
91+
add_library(tinygltf_wrapper INTERFACE)
92+
target_link_libraries(tinygltf_wrapper INTERFACE tinygltf)
93+
target_compile_definitions(tinygltf_wrapper INTERFACE
94+
TINYGLTF_IMPLEMENTATION
95+
TINYGLTF_NO_EXTERNAL_IMAGE
96+
TINYGLTF_NO_STB_IMAGE
97+
TINYGLTF_NO_STB_IMAGE_WRITE
98+
)
99+
if(TARGET nlohmann_json::nlohmann_json)
100+
target_link_libraries(tinygltf_wrapper INTERFACE nlohmann_json::nlohmann_json)
101+
endif()
102+
add_library(tinygltf::tinygltf ALIAS tinygltf_wrapper)
103+
endif()
104+
105+
set(TinyGLTF_FOUND TRUE)
106+
endif()

attachments/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
77
find_package (glfw3 REQUIRED)
88
find_package (glm REQUIRED)
99
find_package (Vulkan REQUIRED)
10+
find_package (tinyobjloader REQUIRED)
11+
find_package (TinyGLTF REQUIRED)
12+
find_package (KTX REQUIRED)
1013

1114
# set up Vulkan C++ module
1215
add_library(VulkanCppModule)
@@ -35,8 +38,6 @@ target_sources(VulkanCppModule
3538
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
3639
)
3740

38-
find_package (tinyobjloader REQUIRED)
39-
4041
find_package (PkgConfig)
4142
pkg_get_variable (STB_INCLUDEDIR stb includedir)
4243
if (NOT STB_INCLUDEDIR)
@@ -249,3 +250,9 @@ add_chapter (34_android
249250
MODELS viking_room.obj
250251
TEXTURES viking_room.png
251252
LIBS glm::glm tinyobjloader::tinyobjloader)
253+
254+
add_chapter (35_gltf_ktx
255+
SHADER 27_shader_depth
256+
MODELS viking_room.glb
257+
TEXTURES viking_room.ktx2
258+
LIBS glm::glm tinygltf::tinygltf KTX::ktx)

attachments/android/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Android Project for Vulkan Tutorial
2+
3+
This Android project allows you to run different chapters of the Vulkan Tutorial on Android devices.
4+
5+
## Selecting a Chapter
6+
7+
By default, the project builds and runs the `34_android` chapter. You can select a different chapter by setting the `chapter` property in your Gradle build.
8+
9+
### Available Chapters
10+
11+
- `34_android`: The Android chapter that uses tinyobjloader to load OBJ models
12+
- `35_gltf_ktx`: The glTF and KTX chapter that uses tinygltf to load glTF models and KTX to load KTX2 textures
13+
14+
### How to Select a Chapter
15+
16+
#### From the Command Line
17+
18+
```bash
19+
./gradlew assembleDebug -Pchapter=35_gltf_ktx
20+
```
21+
22+
#### From Android Studio
23+
24+
1. Edit the `gradle.properties` file in the project root directory
25+
2. Add the following line:
26+
```
27+
chapter=35_gltf_ktx
28+
```
29+
3. Sync the project and build
30+
31+
## Adding New Chapters
32+
33+
To add support for a new chapter:
34+
35+
1. Add the chapter name to the `SUPPORTED_CHAPTERS` list in `app/src/main/cpp/CMakeLists.txt`
36+
2. Add any chapter-specific libraries and compile definitions in the same file
37+
3. Make sure the chapter's source file exists in the `attachments` directory
38+
39+
For example, to add support for a hypothetical `36_new_feature` chapter:
40+
41+
```cmake
42+
# Define the list of supported chapters
43+
set(SUPPORTED_CHAPTERS
44+
"34_android"
45+
"35_gltf_ktx"
46+
"36_new_feature"
47+
)
48+
49+
# Add chapter-specific libraries and definitions
50+
if(CHAPTER STREQUAL "34_android")
51+
# ...
52+
elseif(CHAPTER STREQUAL "35_gltf_ktx")
53+
# ...
54+
elseif(CHAPTER STREQUAL "36_new_feature")
55+
target_link_libraries(vulkan_tutorial_android
56+
# Add any required libraries here
57+
)
58+
59+
target_compile_definitions(vulkan_tutorial_android PRIVATE
60+
# Add any required compile definitions here
61+
)
62+
endif()
63+
```

attachments/android/app/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ android {
1010
targetSdkVersion 33
1111
versionCode 1
1212
versionName "1.0"
13+
14+
// Define which chapter to build (default to 34_android)
15+
buildConfigField "String", "CHAPTER", "\"${project.findProperty('chapter') ?: '34_android'}\""
1316
}
1417

1518
buildTypes {
@@ -28,6 +31,7 @@ android {
2831
cmake {
2932
path "src/main/cpp/CMakeLists.txt"
3033
version "3.22.1"
34+
arguments "-DCHAPTER=${project.findProperty('chapter') ?: '34_android'}"
3135
}
3236
}
3337

0 commit comments

Comments
 (0)