Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 39 additions & 37 deletions attachments/simple_engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,21 @@ project(SimpleEngine VERSION 1.0.0 LANGUAGES CXX C)
# Add CMake module path for custom find modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../CMake")

if(ANDROID)
include(FetchContent)
FetchContent_Declare(
VulkanHeaders
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers.git
GIT_TAG v1.3.275 # Or a specific tag/commit This needs to correspond to the NDK version of Vulkan.
)
FetchContent_MakeAvailable(VulkanHeaders)
endif ()

# Find required packages
find_package (glfw3 REQUIRED)
find_package (glm REQUIRED)
find_package (Vulkan REQUIRED)
find_package (tinygltf REQUIRED)
find_package (KTX REQUIRED)
find_package (OpenAL REQUIRED)

# set up Vulkan C++ module
add_library(VulkanCppModule)
add_library(Vulkan::cppm ALIAS VulkanCppModule)

target_compile_definitions(VulkanCppModule
PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
)
target_include_directories(VulkanCppModule
PRIVATE
"${Vulkan_INCLUDE_DIR}"
)
target_link_libraries(VulkanCppModule
PUBLIC
Vulkan::Vulkan
)

set_target_properties(VulkanCppModule PROPERTIES CXX_STANDARD 20)

target_sources(VulkanCppModule
PUBLIC
FILE_SET cxx_modules TYPE CXX_MODULES
BASE_DIRS
"${Vulkan_INCLUDE_DIR}"
FILES
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
)



# Platform-specific settings
Expand All @@ -52,6 +32,8 @@ if(ANDROID)
else()
# Desktop-specific settings
add_definitions(-DPLATFORM_DESKTOP)
find_package (glfw3 REQUIRED)
find_package (OpenAL REQUIRED)
endif()

# Shader compilation
Expand Down Expand Up @@ -117,22 +99,42 @@ set(SOURCES
mikktspace.c
)

# Create executable
add_executable(SimpleEngine ${SOURCES})
# Create executable or library based on the platform
if(ANDROID)
add_library(SimpleEngine STATIC ${SOURCES})
else()
add_executable(SimpleEngine ${SOURCES})
endif()

add_dependencies(SimpleEngine shaders)
set_target_properties (SimpleEngine PROPERTIES CXX_STANDARD 20)

# Link libraries
target_link_libraries(SimpleEngine PRIVATE
Vulkan::cppm
target_link_libraries(SimpleEngine PUBLIC
Vulkan::Vulkan
Vulkan::Headers
glm::glm
tinygltf::tinygltf
KTX::ktx
OpenAL::OpenAL
)

if(NOT ANDROID)
target_link_libraries(SimpleEngine PRIVATE glfw)
if(ANDROID)
target_link_libraries(SimpleEngine PUBLIC
android
log
EGL
GLESv2
game-activity::game-activity
OpenSLES
)
target_include_directories(SimpleEngine PUBLIC
${VulkanHeaders_SOURCE_DIR}/include
${ANDROID_NDK}/sources/android/native_app_glue
)
target_compile_definitions(SimpleEngine PRIVATE VULKAN_HPP_NO_STRUCT_CONSTRUCTORS)
else()
target_link_libraries(SimpleEngine PRIVATE glfw OpenAL::OpenAL)
target_compile_definitions(SimpleEngine PRIVATE VULKAN_HPP_NO_STRUCT_CONSTRUCTORS VULKAN_HPP_DISPATCH_LOADER_DYNAMIC)
endif()

# Copy model and texture files if they exist
Expand Down
51 changes: 51 additions & 0 deletions attachments/simple_engine/android/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
= Android Project for Vulkan Game Engine Tutorial

This Android project allows you to run the Game Engine's example code in Android. It demonstrates how to manage a non-trivial project across Desktop and mobile environments from the same code base.

== Project Overview

The Vulkan Game Engine Tutorial is a comprehensive learning project that showcases modern graphics programming using the Vulkan API.
This Android port enables running the same engine code on mobile devices, demonstrating cross-platform development practices.

== Prerequisites

* Android Studio 4.2 or higher
* Android NDK r21 or higher
* CMake 3.10+
* Vulkan SDK
* Android device with Vulkan support (Android 7.0+)

== Building and Running

1. Open the project in Android Studio
2. Sync Gradle files
3. Build the project
4. Run on your Android device or emulator

== Project Structure

* `app/` - Android-specific code and resources
* `src/` - Shared C++ engine code
* `assets/` - Shared game assets and shaders (automatically copied by Gradle)
** `models/` - GLTF/GLB model files
** `shaders/` - Compiled SPIR-V shader files
** `textures/` - Texture assets
* `CMake/` - Build configuration files

== Asset Management

The project uses Gradle to automatically handle asset deployment.
Place your assets in the following source locations:

* Source assets location: `<project_root>/assets/`
* Gradle will automatically copy assets to: `app/src/main/assets/`
* Asset changes will be synchronized during build

== Key Components

* GLTF model loading support
* Cross-platform rendering pipeline
* JSON configuration using nlohmann_json
* Unified asset management system with Gradle automation

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.
64 changes: 64 additions & 0 deletions attachments/simple_engine/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
plugins {
id 'com.android.application'
}

android {
namespace "com.simple_engine"
compileSdk 36
defaultConfig {
applicationId "com.simple_engine"
minSdk 24
targetSdk 36
versionCode 1
versionName "1.0"

externalNativeBuild {
cmake {
abiFilters 'arm64-v8a', 'x86_64'
}
}
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}

externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "4.0.2+"
}
}

ndkVersion "28.1.13356709"

// Use assets from the dedicated assets directory and locally compiled shaders
sourceSets {
main {
assets {
srcDirs = [
// Point to the dedicated assets directory
'../../Assets/'
]
}
}
}
buildFeatures {
prefab true
buildConfig true
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.games:games-activity:4.0.0'
}
29 changes: 29 additions & 0 deletions attachments/simple_engine/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Declare that this app uses Vulkan -->
<uses-feature android:name="android.hardware.vulkan.version" android:version="0x400003" android:required="true" />
<uses-feature android:name="android.hardware.vulkan.level" android:version="0" android:required="true" />

<application
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:dataExtractionRules="@xml/data_extraction_rules"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".VulkanActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="simple_engine_android" />
</activity>
</application>

</manifest>
29 changes: 29 additions & 0 deletions attachments/simple_engine/android/app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.22.1)

project(simple_engine_android)

# Add the parent project's cmake folder to the module path
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/CMake")

# Include the game-activity library
find_package(game-activity REQUIRED CONFIG)

# Set C++ standard to match the main project
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add the simple_engine project as a subdirectory
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../.." simple_engine_build)

# Add the main native library
add_library(simple_engine_android SHARED
game_activity_bridge.cpp
)

# Link against libraries
target_link_libraries(simple_engine_android
SimpleEngine
game-activity::game-activity
android
log
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Intentionally empty bridge: rely entirely on GameActivity's native_app_glue
// provided by the prefab (libgame-activity). That glue will invoke our
// android_main(android_app*) defined in main.cpp. Defining another
// GameActivity_onCreate here causes duplicate symbol linker errors.
// Keeping a translation unit avoids removing the target from CMake.

#include <android/log.h>

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "SimpleEngine", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "SimpleEngine", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "SimpleEngine", __VA_ARGS__))

// Nothing to do here.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.simple_engine;

import android.os.Bundle;
import android.view.WindowManager;
import com.google.androidgamesdk.GameActivity;

public class VulkanActivity extends GameActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Keep the screen on while the app is running
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

// Load the native library
static {
System.loadLibrary("simple_engine_android");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Simple Engine</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<!-- Base application theme -->
<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar">
<!-- Customize your theme here -->
</style>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<!-- Backup everything by default -->
<include domain="root" path="."/>
<include domain="file" path="."/>
<include domain="database" path="."/>
<include domain="sharedpref" path="."/>
<include domain="external" path="."/>
</full-backup-content>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<!-- Include all data by default -->
<include domain="root" path="."/>
<include domain="file" path="."/>
<include domain="database" path="."/>
<include domain="sharedpref" path="."/>
<include domain="external" path="."/>
</cloud-backup>
<device-transfer>
<!-- Include all data by default -->
<include domain="root" path="."/>
<include domain="file" path="."/>
<include domain="database" path="."/>
<include domain="sharedpref" path="."/>
<include domain="external" path="."/>
</device-transfer>
</data-extraction-rules>
18 changes: 18 additions & 0 deletions attachments/simple_engine/android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.13.1'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

// For Gradle 9.0+, use the Delete interface instead of type
tasks.register('clean', Delete) {
delete rootProject.buildDir
}
10 changes: 10 additions & 0 deletions attachments/simple_engine/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
android.useAndroidX=true
android.enableJetifier=false

# Gradle 9.0+ compatibility settings
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.caching=true
android.nonTransitiveRClass=true
android.nonFinalResIds=true
org.gradle.configuration-cache=true
Loading
Loading