Skip to content
Open
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
2 changes: 1 addition & 1 deletion backends/imgui_impl_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_android.h"
#include <time.h>
#include <ctime>
#include <android/native_window.h>
#include <android/input.h>
#include <android/keycodes.h>
Expand Down
39 changes: 39 additions & 0 deletions examples/example_android_vulkan/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

cmake_minimum_required(VERSION 3.22.1)

project(ImGuiExample)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..)

add_library(${CMAKE_PROJECT_NAME} SHARED
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
${IMGUI_DIR}/imgui.cpp
${IMGUI_DIR}/imgui_demo.cpp
${IMGUI_DIR}/imgui_draw.cpp
${IMGUI_DIR}/imgui_tables.cpp
${IMGUI_DIR}/imgui_widgets.cpp
${IMGUI_DIR}/backends/imgui_impl_android.cpp
${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c
)

target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${IMGUI_DIR}
${IMGUI_DIR}/backends
${ANDROID_NDK}/sources/android/native_app_glue
)

set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")

target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
android
vulkan
log
)
15 changes: 15 additions & 0 deletions examples/example_android_vulkan/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
1 change: 1 addition & 0 deletions examples/example_android_vulkan/android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
166 changes: 166 additions & 0 deletions examples/example_android_vulkan/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import java.net.HttpURLConnection
import java.net.URI
import java.util.zip.ZipFile

plugins {
alias(libs.plugins.android.application)
}

abstract class FetchVkValidationLayersTask : DefaultTask() {

@get:OutputDirectory
abstract val outputDir: DirectoryProperty

private val validationLayersRoot =
project.layout.buildDirectory.dir(
"generated/vulkanValidationLayers"
)
private val markerFile = validationLayersRoot.map { it.file(".version") }
private val cachedZip = validationLayersRoot.map { it.file("validationLayers.zip") }
private val validationAbis = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64")

@TaskAction
fun run() {
println("Resolving latest Vulkan ValidationLayers release...")

val url = "https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/latest"
val connection = URI(url).toURL().openConnection() as HttpURLConnection
connection.instanceFollowRedirects = false

// /KhronosGroup/Vulkan-ValidationLayers/releases/tag/vulkan-sdk-<version>
val redirect = connection.getHeaderField("Location") ?: error("Failed to resolve latest release")
val tag = redirect.substringAfterLast("/")
val version = tag.removePrefix("vulkan-sdk-")

println("Latest Vulkan ValidationLayers version: $version")

val marker = markerFile.get().asFile

if (marker.exists() && marker.readText().trim() == version) {
println("Validation layers already up to date.")
return
}

val zipFile = cachedZip.get().asFile
if (!zipFile.exists()) {
val zipUrl =
"https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/$tag/android-binaries-$version.zip"

zipFile.parentFile.mkdirs()
println("Downloading Vulkan validation layers...")

URI(zipUrl)
.toURL()
.openStream()
.use { input ->
zipFile.outputStream().use { output ->
input.copyTo(output)
}
}
}

val outDir = outputDir.get().asFile

outDir.deleteRecursively()
outDir.mkdirs()

println("Extracting validation layers...")

ZipFile(zipFile).use { zip ->
validationAbis.forEach { abi ->
val entryName = "$abi/libVkLayer_khronos_validation.so"
val entry = zip.entries()
.asSequence()
.firstOrNull { it.name.endsWith(entryName) }
?: error("Missing $entryName")

val outFile = File(outDir, entryName)
outFile.parentFile.mkdirs()

zip.getInputStream(entry).use { input ->
outFile.outputStream().use { output ->
input.copyTo(output)
}
}
}
}

marker.writeText(version)
println("Validation layers updated to $version")
}
}

val fetchVkValidationLayers by tasks.registering(FetchVkValidationLayersTask::class) {
outputDir.set(
layout.buildDirectory.dir(
"generated/vulkanValidationLayers/jniLibs"
)
)

onlyIf {
gradle.startParameter.taskNames.any {
it.contains("Debug", ignoreCase = true)
}
}
}

android {
ndkVersion = "29.0.14206865"
namespace = "imgui.example.android.vulkan"

compileSdk {
version = release(37)
}

defaultConfig {
applicationId = "imgui.example.android.vulkan"
minSdk = 30
targetSdk = 37
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

@Suppress("UnstableApiUsage")
externalNativeBuild {
cmake {
cppFlags += "-DVK_USE_PLATFORM_ANDROID_KHR"
arguments += "-DANDROID_STL=c++_static"
}
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

externalNativeBuild {
cmake {
path = file("../../CMakeLists.txt")
version = "3.22.1"
}
}
}

dependencies {
implementation(libs.androidx.appcompat)
implementation(libs.androidx.core.ktx)
implementation(libs.material)
}

androidComponents {
onVariants(selector().withBuildType("debug")) { variant ->
variant.sources.jniLibs?.addGeneratedSourceDirectory(
fetchVkValidationLayers,
FetchVkValidationLayersTask::outputDir
)
}
}
21 changes: 21 additions & 0 deletions examples/example_android_vulkan/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:allowBackup="false"
android:fullBackupContent="false"
android:label="ImGuiExample Vulkan"
android:supportsRtl="true">
<activity
android:name=".MainActivity"
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="ImGuiExample" />
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package imgui.example.android.vulkan

import android.app.NativeActivity
import android.view.KeyEvent
import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
import java.util.concurrent.LinkedBlockingQueue

class MainActivity : NativeActivity() {

fun showSoftInput() {
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(this.window.decorView, 0)
}

fun hideSoftInput() {
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(this.window.decorView.windowToken, 0)
}

// Queue for the Unicode characters to be polled from native code (via pollUnicodeChar())
private var unicodeCharacterQueue: LinkedBlockingQueue<Int> = LinkedBlockingQueue()

// We assume dispatchKeyEvent() of the NativeActivity is actually called for every
// KeyEvent and not consumed by any View before it reaches here
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
unicodeCharacterQueue.offer(event.getUnicodeChar(event.metaState))
}
return super.dispatchKeyEvent(event)
}

fun pollUnicodeChar(): Int {
return unicodeCharacterQueue.poll() ?: 0
}

override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) hideSystemUi()
}

private fun hideSystemUi() {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, window.decorView).apply {
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
hide(WindowInsets.Type.systemBars())
}
}
}
4 changes: 4 additions & 0 deletions examples/example_android_vulkan/android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
}
15 changes: 15 additions & 0 deletions examples/example_android_vulkan/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73bcfb608d1fde9fb62e462f834a3299/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/846ee0d876d26a26f37aa1ce8de73224/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9482ddec596298c84656d31d16652665/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/39701d92e1756bb2f141eb67cd4c660e/redirect
toolchainVersion=21
22 changes: 22 additions & 0 deletions examples/example_android_vulkan/android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[versions]
agp = "9.2.0-rc01"
coreKtx = "1.18.0"
junit = "4.13.2"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
appcompat = "1.7.1"
material = "1.13.0"
gamesActivity = "4.0.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-games-activity = { group = "androidx.games", name = "games-activity", version.ref = "gamesActivity" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

Binary file not shown.
Loading