From 786e43384d505a62d29e7962413a36dadfc21453 Mon Sep 17 00:00:00 2001 From: saschawillems Date: Mon, 21 Mar 2016 22:41:27 +0100 Subject: [PATCH] Android support for texture example (#97) --- texture/texture.cpp | 66 ++++++++++++++++++++++++++++++++----------- triangle/triangle.cpp | 14 ++------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/texture/texture.cpp b/texture/texture.cpp index e0d183f1..a62b92ba 100644 --- a/texture/texture.cpp +++ b/texture/texture.cpp @@ -173,14 +173,30 @@ public: 1, &imageMemoryBarrier); } - void loadTexture(const char* fileName, VkFormat format, bool forceLinearTiling) + void loadTexture(std::string fileName, VkFormat format, bool forceLinearTiling) { +#if defined(__ANDROID__) + // Textures are stored inside the apk on Android (compressed) + // So they need to be loaded via the asset manager + AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, fileName.c_str(), AASSET_MODE_STREAMING); + assert(asset); + size_t size = AAsset_getLength(asset); + assert(size > 0); + + void *textureData = malloc(size); + AAsset_read(asset, textureData, size); + AAsset_close(asset); + + gli::texture2D tex2D(gli::load((const char*)textureData, size)); +#else + gli::texture2D tex2D(gli::load(fileName)); +#endif + + assert(!tex2D.empty()); + VkFormatProperties formatProperties; VkResult err; - gli::texture2D tex2D(gli::load(fileName)); - assert(!tex2D.empty()); - texture.width = tex2D[0].dimensions().x; texture.height = tex2D[0].dimensions().y; texture.mipLevels = tex2D.levels(); @@ -772,8 +788,8 @@ public: // Load shaders std::array shaderStages; - shaderStages[0] = loadShader("./../data/shaders/texture.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); - shaderStages[1] = loadShader("./../data/shaders/texture.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + shaderStages[0] = loadShader(getAssetPath() + "shaders/texture.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaderStages[1] = loadShader(getAssetPath() + "shaders/texture.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( @@ -838,7 +854,7 @@ public: setupVertexDescriptions(); prepareUniformBuffers(); loadTexture( - "./../data/textures/igor_and_pal_bc3.ktx", + getAssetPath() + "textures/igor_and_pal_bc3.ktx", VK_FORMAT_BC3_UNORM_BLOCK, false); setupDescriptorSetLayout(); @@ -880,8 +896,7 @@ public: VulkanExample *vulkanExample; -#ifdef _WIN32 - +#if defined(_WIN32) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (vulkanExample != NULL) @@ -902,9 +917,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) @@ -914,21 +927,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 } diff --git a/triangle/triangle.cpp b/triangle/triangle.cpp index c0b26ad3..0cd9f90b 100644 --- a/triangle/triangle.cpp +++ b/triangle/triangle.cpp @@ -25,10 +25,6 @@ #include #include "vulkanexamplebase.h" -#ifdef __ANDROID__ -#include "vulkanandroid.h" -#endif - #define VERTEX_BUFFER_BIND_ID 0 // Set to "true" to enable Vulkan's validation layers // See vulkandebug.cpp for details @@ -871,7 +867,7 @@ public: VulkanExample *vulkanExample; -#ifdef _WIN32 +#if defined(_WIN32) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (vulkanExample != NULL) @@ -880,12 +876,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } -#endif - -#ifdef __linux__ -#ifdef __ANDROID__ - // todo : android event handling -#else +#elif defined(__linux__) && !defined(__ANDROID__) static void handleEvent(const xcb_generic_event_t *event) { if (vulkanExample != NULL) @@ -894,7 +885,6 @@ static void handleEvent(const xcb_generic_event_t *event) } } #endif -#endif // Main entry point #if defined(_WIN32)