Skip to content

Commit bb9cb29

Browse files
committed
Introduce Android support alongside Vulkan Game Engine updates and refactorings:
- Add Android project files (`settings.gradle`, `gradle.properties`, `build.gradle`, `README.adoc`). - Implement Android compatibility via `PLATFORM_ANDROID` macros and input handling changes. - Adjust Vulkan surface interactions to handle shared pointers. - Refactor descriptor and resource logic for improved null checking and initialization. - Enhance code formatting, readability, and consistency across `renderer_pipelines`, `ray_query`, and others. - Update CI systems and improve cross-platform compatibility.
1 parent 66a00ae commit bb9cb29

29 files changed

+14097
-15211
lines changed

.github/workflows/simple_engine_ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,38 @@ jobs:
439439
440440
- name: Test
441441
run: ctest --test-dir build --output-on-failure
442+
443+
android:
444+
name: Build (Android)
445+
runs-on: ubuntu-latest
446+
defaults:
447+
run:
448+
working-directory: attachments/simple_engine/android
449+
steps:
450+
- name: Checkout
451+
uses: actions/checkout@v4
452+
453+
- name: Set up JDK 17
454+
uses: actions/setup-java@v4
455+
with:
456+
java-version: '17'
457+
distribution: 'temurin'
458+
459+
- name: Setup Android SDK
460+
uses: android-actions/setup-android@v3
461+
462+
- name: Cache Gradle packages
463+
uses: actions/cache@v4
464+
with:
465+
path: |
466+
~/.gradle/caches
467+
~/.gradle/wrapper
468+
key: ${{ runner.os }}-gradle-${{ hashFiles('attachments/simple_engine/android/**/*.gradle*', 'attachments/simple_engine/android/**/gradle-wrapper.properties') }}
469+
restore-keys: |
470+
${{ runner.os }}-gradle-
471+
472+
- name: Grant execute permission for gradlew
473+
run: chmod +x ./gradlew
474+
475+
- name: Build Debug APK
476+
run: ./gradlew :app:assembleDebug --stacktrace

attachments/simple_engine/CMakeLists.txt

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ endif()
1414
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
1515

1616
# Find required packages
17-
find_package (glfw3 REQUIRED)
1817
find_package (glm REQUIRED)
1918
find_package (Vulkan REQUIRED)
2019
find_package (tinygltf REQUIRED)
2120
find_package (KTX REQUIRED)
22-
find_package (OpenAL REQUIRED)
21+
22+
# Find or download Vulkan-Hpp headers matching the Vulkan SDK/NDK version
23+
find_package(VulkanHpp REQUIRED)
2324

2425
if(ENABLE_CPP20_MODULE)
2526
# Set up Vulkan C++ module for this standalone project
@@ -32,6 +33,7 @@ if(ENABLE_CPP20_MODULE)
3233
target_include_directories(VulkanCppModule
3334
PUBLIC
3435
"${Vulkan_INCLUDE_DIR}"
36+
"${VulkanHpp_INCLUDE_DIRS}"
3537
)
3638
target_link_libraries(VulkanCppModule
3739
PUBLIC
@@ -44,9 +46,9 @@ if(ENABLE_CPP20_MODULE)
4446
PUBLIC
4547
FILE_SET cxx_modules TYPE CXX_MODULES
4648
BASE_DIRS
47-
"${Vulkan_INCLUDE_DIR}"
49+
"${VulkanHpp_CPPM_DIR}"
4850
FILES
49-
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
51+
"${VulkanHpp_CPPM_DIR}/vulkan/vulkan.cppm"
5052
)
5153

5254
# MSVC-specific options to improve module support
@@ -66,6 +68,7 @@ else()
6668
target_compile_definitions(VulkanCppModule
6769
INTERFACE VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
6870
)
71+
target_include_directories(VulkanCppModule INTERFACE "${VulkanHpp_INCLUDE_DIRS}")
6972
endif()
7073

7174

@@ -74,9 +77,12 @@ endif()
7477
if(ANDROID)
7578
# Android-specific settings
7679
add_definitions(-DPLATFORM_ANDROID)
80+
find_package(game-activity REQUIRED CONFIG)
7781
else()
7882
# Desktop-specific settings
7983
add_definitions(-DPLATFORM_DESKTOP)
84+
find_package(glfw3 REQUIRED)
85+
find_package(OpenAL REQUIRED)
8086
endif()
8187

8288
# Shader compilation
@@ -112,8 +118,9 @@ else()
112118
endif()
113119

114120
# Source files
115-
set(SOURCES
116-
main.cpp
121+
# NOTE: Android builds include this project via `add_subdirectory(...)` from
122+
# `android/app/src/main/cpp/CMakeLists.txt`, so we must not require a desktop `main()`.
123+
set(SOURCES_COMMON
117124
engine.cpp
118125
scene_loading.cpp
119126
platform.cpp
@@ -145,8 +152,19 @@ set(SOURCES
145152
mikktspace.c
146153
)
147154

148-
# Create executable
149-
add_executable(SimpleEngine ${SOURCES})
155+
set(SOURCES_DESKTOP
156+
main.cpp
157+
)
158+
159+
# Create target
160+
if (ANDROID)
161+
# Android: build the engine as a library to be linked into the app's `simple_engine_android` SHARED library.
162+
add_library(SimpleEngine STATIC ${SOURCES_COMMON})
163+
else ()
164+
# Desktop: build the runnable executable (unchanged behavior vs `HEAD`).
165+
add_executable(SimpleEngine ${SOURCES_COMMON} ${SOURCES_DESKTOP})
166+
endif ()
167+
150168
add_dependencies(SimpleEngine shaders)
151169
set_target_properties (SimpleEngine PROPERTIES CXX_STANDARD 20)
152170

@@ -162,20 +180,21 @@ target_compile_definitions(SimpleEngine PRIVATE
162180
# Prefer the Vulkan C++ module target when available (configured at the parent level),
163181
# but fall back to the standard Vulkan library otherwise.
164182
if(TARGET Vulkan::cppm)
165-
target_link_libraries(SimpleEngine PRIVATE Vulkan::cppm)
183+
target_link_libraries(SimpleEngine PUBLIC Vulkan::cppm)
166184
else()
167-
target_link_libraries(SimpleEngine PRIVATE Vulkan::Vulkan)
185+
target_link_libraries(SimpleEngine PUBLIC Vulkan::Vulkan)
168186
endif()
169187

170-
target_link_libraries(SimpleEngine PRIVATE
188+
target_link_libraries(SimpleEngine PUBLIC
171189
glm::glm
172190
tinygltf::tinygltf
173191
KTX::ktx
174-
OpenAL::OpenAL
175192
)
176193

177-
if(NOT ANDROID)
178-
target_link_libraries(SimpleEngine PRIVATE glfw)
194+
if (ANDROID)
195+
target_link_libraries(SimpleEngine PUBLIC game-activity::game-activity OpenSLES android log)
196+
else ()
197+
target_link_libraries(SimpleEngine PRIVATE glfw OpenAL::OpenAL)
179198
endif()
180199

181200
# Windows/MSVC portability and build settings
@@ -207,18 +226,22 @@ endif()
207226

208227
# Copy model and texture files if they exist
209228
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/models)
229+
if (NOT ANDROID)
210230
add_custom_command(TARGET SimpleEngine POST_BUILD
211231
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/models
212232
COMMENT "Copying models to output directory"
213233
)
214234
endif()
235+
endif ()
215236

216237
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/textures)
238+
if (NOT ANDROID)
217239
add_custom_command(TARGET SimpleEngine POST_BUILD
218240
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/textures ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/textures
219241
COMMENT "Copying textures to output directory"
220242
)
221243
endif()
244+
endif ()
222245

223246
# Add packaging configuration
224247
include(CPack)
@@ -254,6 +277,7 @@ else()
254277
endif()
255278

256279
# Include binary and resource directories in the package
280+
if (NOT ANDROID)
257281
install(TARGETS SimpleEngine DESTINATION bin)
258282
if(SLANGC_EXECUTABLE)
259283
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders DESTINATION share/SimpleEngine)
@@ -272,3 +296,4 @@ endif()
272296
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
273297
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.md DESTINATION share/SimpleEngine)
274298
endif()
299+
endif ()
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
= Android Project for Vulkan Game Engine Tutorial
2+
3+
This Android project allows you to run the Game Engine's example code in Android.
4+
It demonstrates how to manage a non-trivial project across Desktop and mobile environments from the same code base.
5+
6+
== Project Overview
7+
8+
The Vulkan Game Engine Tutorial is a comprehensive learning project that showcases modern graphics programming using the Vulkan API.
9+
This Android port enables running the same engine code on mobile devices, demonstrating cross-platform development practices.
10+
11+
== Prerequisites
12+
13+
* Android Studio 4.2 or higher
14+
* Android NDK r21 or higher
15+
* CMake 3.10+
16+
* Vulkan SDK
17+
* Android device with Vulkan support (Android 7.0+)
18+
19+
== Building and Running
20+
21+
1. Open the project in Android Studio
22+
2. Sync Gradle files
23+
3. Build the project
24+
4. Run on your Android device or emulator
25+
26+
== Project Structure
27+
28+
* `app/` - Android-specific code and resources
29+
* `src/` - Shared C++ engine code
30+
* `assets/` - Shared game assets and shaders (automatically copied by Gradle)
31+
** `models/` - GLTF/GLB model files
32+
** `shaders/` - Compiled SPIR-V shader files
33+
** `textures/` - Texture assets
34+
* `CMake/` - Build configuration files
35+
36+
== Asset Management
37+
38+
The project uses Gradle to automatically handle asset deployment.
39+
Place your assets in the following source locations:
40+
41+
* Source assets location: `<project_root>/assets/`
42+
* Gradle will automatically copy assets to: `app/src/main/assets/`
43+
* Asset changes will be synchronized during build
44+
45+
== Key Components
46+
47+
* GLTF model loading support
48+
* Cross-platform rendering pipeline
49+
* JSON configuration using nlohmann_json
50+
* Unified asset management system with Gradle automation
51+
52+
The project demonstrates professional-grade techniques for maintaining a single codebase that targets both desktop and mobile platforms while leveraging modern C++20 features and Vulkan's cross-platform capabilities.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
plugins {
2+
id 'com.android.application'
3+
}
4+
5+
android {
6+
namespace "com.simple_engine"
7+
compileSdk 36
8+
defaultConfig {
9+
applicationId "com.simple_engine"
10+
minSdk 24
11+
targetSdk 36
12+
versionCode 1
13+
versionName "1.0"
14+
15+
externalNativeBuild {
16+
cmake {
17+
abiFilters 'arm64-v8a', 'x86_64'
18+
}
19+
}
20+
}
21+
22+
buildTypes {
23+
release {
24+
minifyEnabled false
25+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26+
}
27+
}
28+
29+
compileOptions {
30+
sourceCompatibility JavaVersion.VERSION_11
31+
targetCompatibility JavaVersion.VERSION_11
32+
}
33+
34+
externalNativeBuild {
35+
cmake {
36+
path "src/main/cpp/CMakeLists.txt"
37+
version "4.0.2+"
38+
}
39+
}
40+
41+
ndkVersion "28.1.13356709"
42+
43+
// Use assets from the dedicated assets directory and locally compiled shaders
44+
sourceSets {
45+
main {
46+
assets {
47+
srcDirs = [
48+
// Point to the dedicated assets directory
49+
'../../Assets/'
50+
]
51+
}
52+
}
53+
}
54+
buildFeatures {
55+
prefab true
56+
buildConfig true
57+
}
58+
}
59+
60+
dependencies {
61+
implementation 'androidx.appcompat:appcompat:1.7.1'
62+
implementation 'com.google.android.material:material:1.12.0'
63+
implementation 'androidx.games:games-activity:4.0.0'
64+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
<!-- Declare that this app uses Vulkan -->
4+
<uses-feature android:name="android.hardware.vulkan.version" android:version="0x400003" android:required="true"/>
5+
<uses-feature android:name="android.hardware.vulkan.level" android:version="0" android:required="true"/>
6+
7+
<application
8+
android:allowBackup="true"
9+
android:fullBackupContent="@xml/backup_rules"
10+
android:dataExtractionRules="@xml/data_extraction_rules"
11+
android:label="@string/app_name"
12+
android:supportsRtl="true"
13+
android:theme="@style/AppTheme">
14+
<activity
15+
android:name=".VulkanActivity"
16+
android:configChanges="orientation|keyboardHidden|screenSize"
17+
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
18+
android:exported="true">
19+
<intent-filter>
20+
<action android:name="android.intent.action.MAIN"/>
21+
<category android:name="android.intent.category.LAUNCHER"/>
22+
</intent-filter>
23+
<meta-data
24+
android:name="android.app.lib_name"
25+
android:value="simple_engine_android"/>
26+
</activity>
27+
</application>
28+
29+
</manifest>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
cmake_minimum_required(VERSION 3.22.1)
2+
3+
project(simple_engine_android)
4+
5+
# Add the parent project's cmake folder to the module path
6+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/CMake")
7+
8+
# Include the game-activity library
9+
find_package(game-activity REQUIRED CONFIG)
10+
11+
# Set C++ standard to match the main project
12+
set(CMAKE_CXX_STANDARD 20)
13+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
14+
15+
# Add the simple_engine project as a subdirectory
16+
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../.." simple_engine_build)
17+
18+
# Add the main native library
19+
add_library(simple_engine_android SHARED
20+
game_activity_bridge.cpp
21+
)
22+
23+
# Link against libraries
24+
target_link_libraries(simple_engine_android
25+
SimpleEngine
26+
game-activity::game-activity
27+
android
28+
log
29+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Intentionally empty bridge: rely entirely on GameActivity's native_app_glue
2+
// provided by the prefab (libgame-activity). That glue will invoke our
3+
// android_main(android_app*) defined in main.cpp. Defining another
4+
// GameActivity_onCreate here causes duplicate symbol linker errors.
5+
// Keeping a translation unit avoids removing the target from CMake.
6+
7+
#include <android/log.h>
8+
9+
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "SimpleEngine", __VA_ARGS__))
10+
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "SimpleEngine", __VA_ARGS__))
11+
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "SimpleEngine", __VA_ARGS__))
12+
13+
// Nothing to do here.

0 commit comments

Comments
 (0)