diff --git a/android/build-particlefire.bat b/android/build-particlefire.bat
new file mode 100644
index 00000000..d0fc29c3
--- /dev/null
+++ b/android/build-particlefire.bat
@@ -0,0 +1 @@
+_build particlefire %1
\ No newline at end of file
diff --git a/android/particlefire/.gitignore b/android/particlefire/.gitignore
new file mode 100644
index 00000000..7a5d249c
--- /dev/null
+++ b/android/particlefire/.gitignore
@@ -0,0 +1,10 @@
+/assets/
+/res/
+/bin/
+/libs/
+/obj/
+/build.xml
+/local.properties
+/project.properties
+/proguard-project.txt
+*.apk
\ No newline at end of file
diff --git a/android/particlefire/AndroidManifest.xml b/android/particlefire/AndroidManifest.xml
new file mode 100644
index 00000000..0d76ca23
--- /dev/null
+++ b/android/particlefire/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/particlefire/build.bat b/android/particlefire/build.bat
new file mode 100644
index 00000000..12d78a82
--- /dev/null
+++ b/android/particlefire/build.bat
@@ -0,0 +1,26 @@
+cd jni
+call ndk-build
+if %ERRORLEVEL% EQU 0 (
+ echo ndk-build has failed, build cancelled
+ cd..
+
+ mkdir "assets\shaders\particlefire"
+ xcopy "..\..\data\shaders\particlefire\*.spv" "assets\shaders\particlefire" /Y
+
+ mkdir "assets\textures"
+ xcopy "..\..\data\textures\fireplace_colormap_bc3.ktx" "assets\textures" /Y
+ xcopy "..\..\data\textures\fireplace_normalmap_bc3.ktx" "assets\textures" /Y
+ xcopy "..\..\data\textures\particle_fire.ktx" "assets\textures" /Y
+ xcopy "..\..\data\textures\particle_smoke.ktx" "assets\textures" /Y
+
+ mkdir "assets\models"
+ xcopy "..\..\data\models\fireplace.obj" "assets\models" /Y
+
+ mkdir "res\drawable"
+ xcopy "..\..\android\images\icon.png" "res\drawable" /Y
+
+ call ant debug -Dout.final.file=vulkanParticlefire.apk
+) ELSE (
+ echo error : ndk-build failed with errors!
+ cd..
+)
diff --git a/android/particlefire/jni/Android.mk b/android/particlefire/jni/Android.mk
new file mode 100644
index 00000000..230eda1d
--- /dev/null
+++ b/android/particlefire/jni/Android.mk
@@ -0,0 +1,47 @@
+LOCAL_PATH := $(call my-dir)/../../particlefire
+
+# assimp
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := assimp
+LOCAL_SRC_FILES := $(LOCAL_PATH)/../../libs/assimp/$(TARGET_ARCH_ABI)/libassimp.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# vulkan example
+
+DATADIR := $(LOCAL_PATH)/../../data
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vulkanParticlefire
+
+PROJECT_FILES := $(wildcard $(LOCAL_PATH)/../../particlefire/*.cpp)
+PROJECT_FILES += $(wildcard $(LOCAL_PATH)/../../base/*.cpp)
+
+LOCAL_CPPFLAGS := -std=c++11
+LOCAL_CPPFLAGS += -D__STDC_LIMIT_MACROS
+LOCAL_CPPFLAGS += -DVK_NO_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../external/
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/glm
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/gli
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/assimp
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../base/
+#LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../base/android
+
+LOCAL_SRC_FILES := $(PROJECT_FILES)
+
+LOCAL_LDLIBS := -landroid -llog -lz
+
+LOCAL_DISABLE_FORMAT_STRING_CHECKS := true
+
+LOCAL_STATIC_LIBRARIES += android_native_app_glue
+LOCAL_STATIC_LIBRARIES += cpufeatures
+LOCAL_STATIC_LIBRARIES += libassimp
+
+include $(BUILD_SHARED_LIBRARY)
+
+$(call import-module, android/native_app_glue)
+$(call import-module, android/cpufeatures)
diff --git a/android/particlefire/jni/Application.mk b/android/particlefire/jni/Application.mk
new file mode 100644
index 00000000..62020feb
--- /dev/null
+++ b/android/particlefire/jni/Application.mk
@@ -0,0 +1,5 @@
+APP_PLATFORM := android-19
+APP_ABI := armeabi-v7a
+APP_STL := c++_static
+APP_CPPFLAGS := -std=c++11
+NDK_TOOLCHAIN_VERSION := clang
diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp
index 65bcab89..b10c0bf1 100644
--- a/base/vulkanexamplebase.cpp
+++ b/base/vulkanexamplebase.cpp
@@ -288,7 +288,7 @@ VkBool32 VulkanExampleBase::createBuffer(VkBufferUsageFlags usage, VkDeviceSize
}
void VulkanExampleBase::loadMesh(
- const char * filename,
+ std::string filename,
vkMeshLoader::MeshBuffer * meshBuffer,
std::vector vertexLayout,
float scale)
diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h
index 12e1daad..940bfb8d 100644
--- a/base/vulkanexamplebase.h
+++ b/base/vulkanexamplebase.h
@@ -266,7 +266,7 @@ public:
// Load a mesh (using ASSIMP) and create vulkan vertex and index buffers with given vertex layout
void loadMesh(
- const char *filename,
+ std::string fiename,
vkMeshLoader::MeshBuffer *meshBuffer,
std::vector vertexLayout,
float scale);
diff --git a/particlefire/particlefire.cpp b/particlefire/particlefire.cpp
index 49a8b3c7..6bf169ab 100644
--- a/particlefire/particlefire.cpp
+++ b/particlefire/particlefire.cpp
@@ -361,21 +361,21 @@ public:
{
// Particles
textureLoader->loadTexture(
- "./../data/textures/particle_smoke.ktx",
+ getAssetPath() + "textures/particle_smoke.ktx",
VK_FORMAT_BC3_UNORM_BLOCK,
&textures.particles.smoke);
textureLoader->loadTexture(
- "./../data/textures/particle_fire.ktx",
+ getAssetPath() + "textures/particle_fire.ktx",
VK_FORMAT_BC3_UNORM_BLOCK,
&textures.particles.fire);
// Floor
textureLoader->loadTexture(
- "./../data/textures/fireplace_colormap_bc3.ktx",
+ getAssetPath() + "textures/fireplace_colormap_bc3.ktx",
VK_FORMAT_BC3_UNORM_BLOCK,
&textures.floor.colorMap);
textureLoader->loadTexture(
- "./../data/textures/fireplace_normalmap_bc3.ktx",
+ getAssetPath() + "textures/fireplace_normalmap_bc3.ktx",
VK_FORMAT_BC3_UNORM_BLOCK,
&textures.floor.normalMap);
@@ -405,7 +405,7 @@ public:
void loadMeshes()
{
- loadMesh("./../data/models/fireplace.obj", &meshes.environment.buffers, vertexLayout, 10.0f);
+ loadMesh(getAssetPath() + "models/fireplace.obj", &meshes.environment.buffers, vertexLayout, 10.0f);
meshes.environment.setupVertexInputState(vertexLayout);
}
@@ -669,8 +669,8 @@ public:
// Load shaders
std::array shaderStages;
- shaderStages[0] = loadShader("./../data/shaders/particlefire/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
- shaderStages[1] = loadShader("./../data/shaders/particlefire/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
+ shaderStages[0] = loadShader(getAssetPath() + "shaders/particlefire/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
+ shaderStages[1] = loadShader(getAssetPath() + "shaders/particlefire/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
vkTools::initializers::pipelineCreateInfo(
@@ -705,8 +705,8 @@ public:
assert(!err);
// Environment rendering pipeline (normal mapped)
- shaderStages[0] = loadShader("./../data/shaders/particlefire/normalmap.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
- shaderStages[1] = loadShader("./../data/shaders/particlefire/normalmap.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
+ shaderStages[0] = loadShader(getAssetPath() + "shaders/particlefire/normalmap.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
+ shaderStages[1] = loadShader(getAssetPath() + "shaders/particlefire/normalmap.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
pipelineCreateInfo.pVertexInputState = &meshes.environment.vertexInputState;
blendAttachmentState.blendEnable = VK_FALSE;
depthStencilState.depthWriteEnable = VK_TRUE;
@@ -822,10 +822,10 @@ public:
}
};
+
VulkanExample *vulkanExample;
-#ifdef _WIN32
-
+#if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (vulkanExample != NULL)
@@ -834,9 +834,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
return (DefWindowProc(hWnd, uMsg, wParam, lParam));
}
-
-#else
-
+#elif defined(__linux__) && !defined(__ANDROID__)
static void handleEvent(const xcb_generic_event_t *event)
{
if (vulkanExample != NULL)
@@ -846,21 +844,42 @@ static void handleEvent(const xcb_generic_event_t *event)
}
#endif
-#ifdef _WIN32
+// Main entry point
+#if defined(_WIN32)
+// Windows entry point
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
-#else
+#elif defined(__ANDROID__)
+// Android entry point
+void android_main(android_app* state)
+#elif defined(__linux__)
+// Linux entry point
int main(const int argc, const char *argv[])
#endif
{
+#if defined(__ANDROID__)
+ // Removing this may cause the compiler to omit the main entry point
+ // which would make the application crash at start
+ app_dummy();
+#endif
vulkanExample = new VulkanExample();
-#ifdef _WIN32
+#if defined(_WIN32)
vulkanExample->setupWindow(hInstance, WndProc);
-#else
+#elif defined(__ANDROID__)
+ // Attach vulkan example to global android application state
+ state->userData = vulkanExample;
+ state->onAppCmd = VulkanExample::handleAppCommand;
+ state->onInputEvent = VulkanExample::handleAppInput;
+ vulkanExample->androidApp = state;
+#elif defined(__linux__)
vulkanExample->setupWindow();
#endif
+#if !defined(__ANDROID__)
vulkanExample->initSwapchain();
vulkanExample->prepare();
+#endif
vulkanExample->renderLoop();
+#if !defined(__ANDROID__)
delete(vulkanExample);
return 0;
-}
+#endif
+}
\ No newline at end of file