Skip to content

Commit 0e90d7b

Browse files
committed
Add initial Vulkan Android support
- Introduced Vulkan Android project setup with `AndroidManifest.xml` and platform-specific `34_android.cpp`. - Added cross-platform support for Vulkan initialization, rendering, and asset management between Android and desktop. - Included Android-specific utilities and logging for Vulkan deployment.
1 parent e04bc4c commit 0e90d7b

File tree

12 files changed

+2883
-0
lines changed

12 files changed

+2883
-0
lines changed

attachments/34_android.cpp

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

attachments/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,9 @@ add_chapter (33_vulkan_profiles
243243
MODELS viking_room.obj
244244
TEXTURES viking_room.png
245245
LIBS glm::glm tinyobjloader::tinyobjloader)
246+
247+
add_chapter (34_android
248+
SHADER 27_shader_depth
249+
MODELS viking_room.obj
250+
TEXTURES viking_room.png
251+
LIBS glm::glm tinyobjloader::tinyobjloader)
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+
compileSdkVersion 33
7+
defaultConfig {
8+
applicationId "com.vulkan.tutorial"
9+
minSdkVersion 24
10+
targetSdkVersion 33
11+
versionCode 1
12+
versionName "1.0"
13+
}
14+
15+
buildTypes {
16+
release {
17+
minifyEnabled false
18+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
19+
}
20+
}
21+
22+
compileOptions {
23+
sourceCompatibility JavaVersion.VERSION_1_8
24+
targetCompatibility JavaVersion.VERSION_1_8
25+
}
26+
27+
externalNativeBuild {
28+
cmake {
29+
path "src/main/cpp/CMakeLists.txt"
30+
version "3.22.1"
31+
}
32+
}
33+
34+
ndkVersion "25.2.9519653"
35+
36+
// Use assets from the main project and locally compiled shaders
37+
sourceSets {
38+
main {
39+
assets {
40+
srcDirs = [
41+
// Point to the main project's assets
42+
'../../../../', // For models and textures in the attachments directory
43+
// Use locally compiled shaders from the build directory for all ABIs
44+
// These paths are relative to the app directory
45+
'.externalNativeBuild/cmake/debug/arm64-v8a/shaders',
46+
'.externalNativeBuild/cmake/debug/armeabi-v7a/shaders',
47+
'.externalNativeBuild/cmake/debug/x86/shaders',
48+
'.externalNativeBuild/cmake/debug/x86_64/shaders',
49+
// Also include release build paths
50+
'.externalNativeBuild/cmake/release/arm64-v8a/shaders',
51+
'.externalNativeBuild/cmake/release/armeabi-v7a/shaders',
52+
'.externalNativeBuild/cmake/release/x86/shaders',
53+
'.externalNativeBuild/cmake/release/x86_64/shaders'
54+
]
55+
}
56+
}
57+
}
58+
}
59+
60+
dependencies {
61+
implementation 'androidx.appcompat:appcompat:1.6.1'
62+
implementation 'com.google.android.material:material:1.9.0'
63+
implementation 'com.google.androidgamesdk:game-activity:1.2.0'
64+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.vulkan.tutorial">
4+
5+
<!-- Vulkan requires API level 24 (Android 7.0) or higher -->
6+
<uses-sdk android:minSdkVersion="24" />
7+
8+
<!-- Declare that this app uses Vulkan -->
9+
<uses-feature android:name="android.hardware.vulkan.version" android:version="0x400003" android:required="true" />
10+
<uses-feature android:name="android.hardware.vulkan.level" android:version="0" android:required="true" />
11+
12+
<application
13+
android:allowBackup="true"
14+
android:icon="@mipmap/ic_launcher"
15+
android:label="@string/app_name"
16+
android:roundIcon="@mipmap/ic_launcher_round"
17+
android:supportsRtl="true"
18+
android:theme="@style/AppTheme">
19+
<activity
20+
android:name=".VulkanActivity"
21+
android:label="@string/app_name"
22+
android:configChanges="orientation|keyboardHidden|screenSize"
23+
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
24+
android:exported="true">
25+
<intent-filter>
26+
<action android:name="android.intent.action.MAIN" />
27+
<category android:name="android.intent.category.LAUNCHER" />
28+
</intent-filter>
29+
<meta-data
30+
android:name="android.app.lib_name"
31+
android:value="vulkan_tutorial_android" />
32+
</activity>
33+
</application>
34+
35+
</manifest>
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
cmake_minimum_required(VERSION 3.22.1)
2+
3+
project(vulkan_tutorial_android)
4+
5+
# Set the path to the main CMakeLists.txt relative to this file
6+
set(MAIN_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../CMakeLists.txt")
7+
8+
# Find the Vulkan package
9+
find_package(Vulkan REQUIRED)
10+
11+
# Find the tinyobjloader package
12+
find_package(tinyobjloader REQUIRED)
13+
14+
# Find the glm package
15+
find_package(glm REQUIRED)
16+
17+
# Find the stb_image.h header
18+
find_path(STB_INCLUDEDIR stb_image.h PATH_SUFFIXES stb)
19+
if (NOT STB_INCLUDEDIR)
20+
message(FATAL_ERROR "stb_image.h not found")
21+
endif()
22+
23+
# Set up shader compilation tools
24+
add_executable(glslang::validator IMPORTED)
25+
find_program(GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
26+
set_property(TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}")
27+
28+
# Define shader building function
29+
function(add_shaders_target TARGET)
30+
cmake_parse_arguments("SHADER" "" "CHAPTER_NAME" "SOURCES" ${ARGN})
31+
set(SHADERS_DIR ${SHADER_CHAPTER_NAME}/shaders)
32+
add_custom_command(
33+
OUTPUT ${SHADERS_DIR}
34+
COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR}
35+
)
36+
add_custom_command(
37+
OUTPUT ${SHADERS_DIR}/frag.spv ${SHADERS_DIR}/vert.spv
38+
COMMAND glslang::validator
39+
ARGS --target-env vulkan1.0 ${SHADER_SOURCES} --quiet
40+
WORKING_DIRECTORY ${SHADERS_DIR}
41+
DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES}
42+
COMMENT "Compiling Shaders"
43+
VERBATIM
44+
)
45+
add_custom_target(${TARGET} DEPENDS ${SHADERS_DIR}/frag.spv ${SHADERS_DIR}/vert.spv)
46+
endfunction()
47+
48+
# Include the game-activity library
49+
find_package(game-activity REQUIRED CONFIG)
50+
include_directories(${ANDROID_NDK}/sources/android/game-activity/include)
51+
52+
# Set C++ standard to match the main project
53+
set(CMAKE_CXX_STANDARD 20)
54+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
55+
56+
# Add the Vulkan C++ module
57+
add_library(VulkanCppModule SHARED)
58+
target_compile_definitions(VulkanCppModule
59+
PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
60+
)
61+
target_include_directories(VulkanCppModule
62+
PRIVATE
63+
"${Vulkan_INCLUDE_DIR}"
64+
)
65+
target_link_libraries(VulkanCppModule
66+
PUBLIC
67+
${Vulkan_LIBRARIES}
68+
)
69+
set_target_properties(VulkanCppModule PROPERTIES CXX_STANDARD 20)
70+
71+
# Set up the C++ module file set
72+
target_sources(VulkanCppModule
73+
PUBLIC
74+
FILE_SET cxx_modules TYPE CXX_MODULES
75+
BASE_DIRS
76+
"${Vulkan_INCLUDE_DIR}"
77+
FILES
78+
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
79+
)
80+
81+
# Set up shader compilation for 34_android
82+
set(SHADER_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments")
83+
set(SHADER_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
84+
file(MAKE_DIRECTORY ${SHADER_OUTPUT_DIR})
85+
86+
# Copy shader source files to the build directory
87+
configure_file(
88+
"${SHADER_SOURCE_DIR}/27_shader_depth.frag"
89+
"${SHADER_OUTPUT_DIR}/27_shader_depth.frag"
90+
COPYONLY
91+
)
92+
configure_file(
93+
"${SHADER_SOURCE_DIR}/27_shader_depth.vert"
94+
"${SHADER_OUTPUT_DIR}/27_shader_depth.vert"
95+
COPYONLY
96+
)
97+
98+
# Compile shaders
99+
set(SHADER_SOURCES "${SHADER_OUTPUT_DIR}/27_shader_depth.frag" "${SHADER_OUTPUT_DIR}/27_shader_depth.vert")
100+
add_shaders_target(android_shaders CHAPTER_NAME "${SHADER_OUTPUT_DIR}" SOURCES ${SHADER_SOURCES})
101+
102+
# Add the main native library
103+
add_library(vulkan_tutorial_android SHARED
104+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/34_android.cpp
105+
game_activity_bridge.cpp
106+
)
107+
108+
# Add dependency on shader compilation
109+
add_dependencies(vulkan_tutorial_android android_shaders)
110+
111+
# Set include directories
112+
target_include_directories(vulkan_tutorial_android PRIVATE
113+
${CMAKE_CURRENT_SOURCE_DIR}
114+
${Vulkan_INCLUDE_DIR}
115+
${ANDROID_NDK}/sources/android/game-activity/include
116+
${STB_INCLUDEDIR}
117+
)
118+
119+
# Link against libraries
120+
target_link_libraries(vulkan_tutorial_android
121+
VulkanCppModule
122+
game-activity::game-activity
123+
android
124+
log
125+
${Vulkan_LIBRARIES}
126+
tinyobjloader::tinyobjloader
127+
glm::glm
128+
)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <game-activity/GameActivity.h>
2+
#include <game-activity/native_app_glue/android_native_app_glue.h>
3+
#include <android/log.h>
4+
5+
// Define logging macros
6+
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "VulkanTutorial", __VA_ARGS__))
7+
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "VulkanTutorial", __VA_ARGS__))
8+
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "VulkanTutorial", __VA_ARGS__))
9+
10+
// Forward declaration of the main entry point
11+
extern "C" void android_main(android_app* app);
12+
13+
// GameActivity entry point
14+
extern "C" {
15+
void GameActivity_onCreate(GameActivity* activity) {
16+
LOGI("GameActivity_onCreate");
17+
18+
// Create an android_app structure
19+
android_app* app = new android_app();
20+
memset(app, 0, sizeof(android_app));
21+
22+
// Set up the android_app structure
23+
app->activity = activity;
24+
app->window = activity->window;
25+
26+
// Call the original android_main function
27+
android_main(app);
28+
29+
// Clean up
30+
delete app;
31+
}
32+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.vulkan.tutorial;
2+
3+
import android.os.Bundle;
4+
import android.view.WindowManager;
5+
import com.google.androidgamesdk.GameActivity;
6+
7+
public class VulkanActivity extends GameActivity {
8+
@Override
9+
protected void onCreate(Bundle savedInstanceState) {
10+
super.onCreate(savedInstanceState);
11+
12+
// Keep the screen on while the app is running
13+
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
14+
}
15+
16+
// Load the native library
17+
static {
18+
System.loadLibrary("vulkan_tutorial_android");
19+
}
20+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<string name="app_name">Vulkan Tutorial</string>
3+
</resources>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<resources>
2+
<!-- Base application theme -->
3+
<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar">
4+
<!-- Customize your theme here -->
5+
</style>
6+
</resources>

attachments/android/build.gradle

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2+
buildscript {
3+
repositories {
4+
google()
5+
mavenCentral()
6+
}
7+
dependencies {
8+
classpath 'com.android.tools.build:gradle:7.4.2'
9+
10+
// NOTE: Do not place your application dependencies here; they belong
11+
// in the individual module build.gradle files
12+
}
13+
}
14+
15+
allprojects {
16+
repositories {
17+
google()
18+
mavenCentral()
19+
}
20+
}
21+
22+
task clean(type: Delete) {
23+
delete rootProject.buildDir
24+
}

0 commit comments

Comments
 (0)